(iOS)高仿商城在線

開源項(xiàng)目鏈接:https://github.com/RocketsChen/CDDStore

項(xiàng)目介紹

首頁
項(xiàng)目還是經(jīng)典的 MVC + UITabbarController+UINavigationController架構(gòu)組件而成
展示部分代碼:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    //點(diǎn)擊tabBarItem動(dòng)畫
    [self tabBarButtonClick:[self getTabBarButton]];
}
- (UIControl *)getTabBarButton{
    NSMutableArray *tabBarButtons = [[NSMutableArray alloc]initWithCapacity:0];
    
    for (UIView *tabBarButton in self.tabBar.subviews) {
        if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]){
            [tabBarButtons addObject:tabBarButton];
        }
    }
    UIControl *tabBarButton = [tabBarButtons   objectAtIndex:self.selectedIndex];
    return tabBarButton;
}
#pragma mark - 點(diǎn)擊動(dòng)畫
- (void)tabBarButtonClick:(UIControl *)tabBarButton
{
    for (UIView *imageView in tabBarButton.subviews) {
        if ([imageView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) {
            //需要實(shí)現(xiàn)的幀動(dòng)畫,這里根據(jù)自己需求改動(dòng)
            CAKeyframeAnimation *animation = [CAKeyframeAnimation
                                              animation];
            animation.keyPath = @"transform.scale";
            animation.values = @[@1.0,@1.1,@0.9,@1.0];
            animation.duration = 0.3;
            animation.calculationMode = kCAAnimationCubic;
            //添加動(dòng)畫
            [imageView.layer addAnimation:animation forKey:nil];
        }
    }
}
整個(gè)Demo的數(shù)據(jù)都是通過Charles攔截商品鏈接手寫Plist,然后利用MJExtension字典轉(zhuǎn)模型如下截圖名字起得很隨意勿怪
部分Plist

目前主要實(shí)現(xiàn)的功能

1.初始化項(xiàng)目骨架搭建,首頁、分類、購物車、我的四大模塊的界面
2.本地?cái)?shù)據(jù)庫我的數(shù)據(jù)本地儲(chǔ)存,支持改動(dòng)保存
3.點(diǎn)擊商品分類,進(jìn)入數(shù)據(jù)界面可切換視圖形態(tài),搜索懸停處理,足跡和返回頂部
4.點(diǎn)擊進(jìn)入詳情界面,數(shù)據(jù)傳入,分為商品、詳情、評(píng)價(jià)三大模塊,并在商品界面細(xì)分詳情如果推薦商品,展示部分用戶評(píng)價(jià)(類似國美在線)
分類
詳情
詳情界面分析:主要還是利用UICollectionview來完成商品詳情界面的需求界面原型可參考國美商品詳情,提一句,整個(gè)項(xiàng)目復(fù)雜界面幾乎都是用UICollectionview來完成,95%以上View都是采用純代碼來實(shí)現(xiàn)的(考慮后期重構(gòu))
詳情文件夾截圖
代碼展示:

#pragma mark - 接受通知
- (void)acceptanceNote
{
    //滾動(dòng)到詳情
    __weak typeof(self)weakSlef = self;
    _dcObserve = [[NSNotificationCenter defaultCenter]addObserverForName:@"scrollToDetailsPage" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        [weakSlef topBottonClick:weakSlef.bgView.subviews[1]]; //跳轉(zhuǎn)詳情
    }];
    
    _dcObserve = [[NSNotificationCenter     defaultCenter]addObserverForName:@"scrollToCommentsPage" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        [weakSlef topBottonClick:weakSlef.bgView.subviews[2]]; //跳轉(zhuǎn)到評(píng)論界面
    }];
}
######代碼展示:
#pragma mark - 頭部View
- (void)setUpTopButtonView
{
    NSArray *titles = @[@"商品",@"詳情",@"評(píng)價(jià)"];
    CGFloat margin = 5;
    _bgView = [[UIView alloc] init];
    _bgView.dc_centerX = ScreenW * 0.5;
    _bgView.dc_height = 44;
    _bgView.dc_width = (_bgView.dc_height + margin) * titles.count;
    _bgView.dc_y = 0;
    self.navigationItem.titleView = _bgView;
    
    CGFloat buttonW = _bgView.dc_height;
    CGFloat buttonH = _bgView.dc_height;
    CGFloat buttonY = _bgView.dc_y;
    for (NSInteger i = 0; i < titles.count; i++) {
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setTitle:titles[i] forState:0];
        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        button.tag = i;
        button.titleLabel.font = PFR15Font;
        [button addTarget:self action:@selector(topBottonClick:) forControlEvents:UIControlEventTouchUpInside];
        CGFloat buttonX = i * (buttonW + margin);
        
        button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
        
        [_bgView addSubview:button];
        
    }
    
    UIButton *firstButton = _bgView.subviews[0];
    [self topBottonClick:firstButton]; //默認(rèn)選擇第一個(gè)
    
    UIView *indicatorView = [[UIView alloc]init];
    self.indicatorView = indicatorView;
    indicatorView.backgroundColor = [firstButton titleColorForState:UIControlStateSelected];
    
    indicatorView.dc_height = 2;
    indicatorView.dc_y = _bgView.dc_height - indicatorView.dc_height;
    
    [firstButton.titleLabel sizeToFit];
    indicatorView.dc_width = firstButton.titleLabel.dc_width;
    indicatorView.dc_centerX = firstButton.dc_centerX;
    
    [_bgView addSubview:indicatorView];
}
聲明
 #import "DCDetailShufflingHeadView.h" //頭部輪播
 #import "DCDetailGoodReferralCell.h"  //商品標(biāo)題價(jià)格介紹
 #import "DCDetailShowTypeCell.h"      //種類
 #import "DCShowTypeOneCell.h"         //種類01
 #import "DCShowTypeTwoCell.h"         //種類02
 #import "DCShowTypeThreeCell.h"       //種類03
 #import "DCShowTypeFourCell.h"        //種類04
 #import "DCDetailServicetCell.h"      //服務(wù)
 #import "DCDetailLikeCell.h"         //猜你喜歡
 #import "DCDetailOverFooterView.h"   //尾部結(jié)束
 #import "DCDetailPartCommentCell.h"  //部分評(píng)論
 #import "DCDeatilCustomHeadView.h"  //自定義頭部        

注冊(cè)

 //注冊(cè)header
 [_collectionView registerClass:[DCDetailShufflingHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DCDetailShufflingHeadViewID];
 [_collectionView registerClass:[DCDeatilCustomHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DCDeatilCustomHeadViewID];
 //注冊(cè)Cell
 [_collectionView registerClass:[DCDetailGoodReferralCell class] forCellWithReuseIdentifier:DCDetailGoodReferralCellID];
 [_collectionView registerClass:[DCShowTypeOneCell class] forCellWithReuseIdentifier:DCShowTypeOneCellID];
 [_collectionView registerClass:[DCShowTypeTwoCell class] forCellWithReuseIdentifier:DCShowTypeTwoCellID];
 [_collectionView registerClass:[DCShowTypeThreeCell class] forCellWithReuseIdentifier:DCShowTypeThreeCellID];
 [_collectionView registerClass:[DCShowTypeFourCell class] forCellWithReuseIdentifier:DCShowTypeFourCellID];
 [_collectionView registerClass:[DCDetailLikeCell class] forCellWithReuseIdentifier:DCDetailLikeCellID];
 [_collectionView registerClass:[DCDetailPartCommentCell class] forCellWithReuseIdentifier:DCDetailPartCommentCellID];
 [_collectionView registerClass:[DCDetailServicetCell class] forCellWithReuseIdentifier:DCDetailServicetCellID];
 //注冊(cè)Footer
 [_collectionView registerClass:[DCDetailOverFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:DCDetailOverFooterViewID];
 [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"UICollectionElementKindSectionFooter"]; //間隔

實(shí)現(xiàn)

#pragma mark - <UICollectionViewDataSource>
- (NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 6;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return (section == 0 ||section == 2 || section == 3) ? 2 : 1;
}

#pragma mark - <UICollectionViewDelegate>
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *gridcell = nil;
    DCUserInfo *userInfo = UserInfoData;
    if (indexPath.section == 0) {
        if (indexPath.row == 0) {
            DCDetailGoodReferralCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCDetailGoodReferralCellID forIndexPath:indexPath];
            cell.goodTitleLabel.text = _goodTitle;
            cell.goodPriceLabel.text = [NSString stringWithFormat:@"¥ %@",_goodPrice];
            cell.goodSubtitleLabel.text = _goodSubtitle;
            [DCSpeedy dc_setUpLabel:cell.goodTitleLabel Content:_goodTitle IndentationFortheFirstLineWith:cell.goodPriceLabel.font.pointSize * 2];
            cell.shareButtonClickBlock = ^{
                NSLog(@"點(diǎn)擊了分享");
            };
            gridcell = cell;
        }else if (indexPath.row == 1){
            DCShowTypeFourCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCShowTypeFourCellID forIndexPath:indexPath];
            
            gridcell = cell;
        }
        
    }else if (indexPath.section == 1 || indexPath.section == 2 ){
        if (indexPath.section == 1) {
            DCShowTypeOneCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCShowTypeOneCellID forIndexPath:indexPath];
            cell.contentLabel.text = @"紅色 全網(wǎng)通 1個(gè)";
            gridcell = cell;
        }else{
            if (indexPath.row == 0) {
                DCShowTypeTwoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCShowTypeTwoCellID forIndexPath:indexPath];
                cell.contentLabel.text = userInfo.defaultAddress; //地址
                gridcell = cell;
            }else{
                DCShowTypeThreeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCShowTypeThreeCellID forIndexPath:indexPath];
                gridcell = cell;
            }
        }
    }else if (indexPath.section == 3){
        DCDetailServicetCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCDetailServicetCellID forIndexPath:indexPath];
        NSArray *btnTitles = @[@"以舊換新",@"可選增值服務(wù)"];
        NSArray *btnImages = @[@"detail_xiangqingye_yijiuhuanxin",@"ptgd_icon_zengzhifuwu"];
        NSArray *titles = @[@"以舊換新再送好禮",@"為商品保價(jià)護(hù)航"];
        [cell.serviceButton setTitle:btnTitles[indexPath.row] forState:UIControlStateNormal];
        [cell.serviceButton setImage:[UIImage imageNamed:btnImages[indexPath.row]] forState:UIControlStateNormal];
        cell.serviceLabel.text = titles[indexPath.row];
        if (indexPath.row == 0) {//分割線
            [DCSpeedy dc_setUpLongLineWith:cell WithColor:[[UIColor lightGrayColor]colorWithAlphaComponent:0.4] WithHightRatio:0.6];
        }
        gridcell = cell;
    }else if (indexPath.section == 4){
        DCDetailPartCommentCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCDetailPartCommentCellID forIndexPath:indexPath];
        cell.backgroundColor = [UIColor orangeColor];
        gridcell = cell;
    }else if (indexPath.section == 5){
        DCDetailLikeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:DCDetailLikeCellID forIndexPath:indexPath];
        gridcell = cell;
    }
    
    return gridcell;
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    
    UICollectionReusableView *reusableview = nil;
    if (kind == UICollectionElementKindSectionHeader){
        if (indexPath.section == 0) {
            DCDetailShufflingHeadView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DCDetailShufflingHeadViewID forIndexPath:indexPath];
            headerView.shufflingArray = _shufflingArray;
            reusableview = headerView;
        }else if (indexPath.section == 5){
            DCDeatilCustomHeadView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DCDeatilCustomHeadViewID forIndexPath:indexPath];
            reusableview = headerView;
        }
    }else if (kind == UICollectionElementKindSectionFooter){
        if (indexPath.section == 5) {
            DCDetailOverFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:DCDetailOverFooterViewID forIndexPath:indexPath];
            reusableview = footerView;
        }else{
            UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"UICollectionElementKindSectionFooter" forIndexPath:indexPath];
            footerView.backgroundColor = DCBGColor;
            reusableview = footerView;
        }
    }
    return reusableview;
    
    ;
}

#pragma mark - item寬高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) { //商品詳情
        return (indexPath.row == 0) ? CGSizeMake(ScreenW, [DCSpeedy dc_calculateTextSizeWithText:_goodTitle WithTextFont:16 WithMaxW:ScreenW - DCMargin * 6].height + [DCSpeedy dc_calculateTextSizeWithText:_goodPrice WithTextFont:20 WithMaxW:ScreenW - DCMargin * 6].height + [DCSpeedy dc_calculateTextSizeWithText:_goodSubtitle WithTextFont:12 WithMaxW:ScreenW - DCMargin * 6].height + DCMargin * 4) : CGSizeMake(ScreenW, 35);
    }else{
        return (indexPath.section == 1 || indexPath.section == 2) ? CGSizeMake(ScreenW, 60)  : (indexPath.section == 3) ? CGSizeMake(ScreenW / 2, 60) : (indexPath.section == 4) ?CGSizeMake(ScreenW, 270) :CGSizeMake(ScreenW, (ScreenW / 3 + 60) * 2 + 20);
    }
}

#pragma mark - foot寬高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return (section == 5) ? CGSizeMake(ScreenW, 35) : CGSizeMake(ScreenW, DCMargin);
}

我的

總結(jié)一下

  • 上個(gè)月可能真的有點(diǎn)閑,所以想寫個(gè)開源商城類的Demo,原本以為半個(gè)月左右就能ok了結(jié)果越寫越多,最近想著可能不能一直更新的東西所以先把初步版本開源出來!
  • 項(xiàng)目幾乎是全代碼實(shí)現(xiàn)的,寫得很簡單邏輯也不算復(fù)雜但肯定也會(huì)有很多不足,后續(xù)在更新的同時(shí)會(huì)逐步重構(gòu)!
  • 項(xiàng)目中有問題,Bug等歡迎Issues我!

后續(xù)項(xiàng)目有時(shí)間會(huì)繼續(xù)更新,不斷完善!

我的微博
本項(xiàng)目GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,045評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,327評(píng)論 4 61
  • 把自己活好是最重要的責(zé)任 我們帶著一聲啼哭來到這世界,享受著周邊所有人對(duì)這個(gè)新生命的關(guān)注,還有家人對(duì)你成長的期待。...
    一只介田狗閱讀 647評(píng)論 1 0
  • 哈嘍大家好 今天我就寫一寫我學(xué)動(dòng)畫是做的筆記吧## 首先建立viewController聲明變量@proerty(...
    哈酒拎壺沖閱讀 380評(píng)論 0 3

友情鏈接更多精彩內(nèi)容