为第二个demo加上UITabBarController

实现一共三大个模块,“首页” ,“发现” 和 “我”,“首页”就是第二个demo,“我” 是一个简单的UItableview

 

需要注意的一点是 新增加进来的tabbar会遮挡底部页面。因为“首页”是固定高度,所以在设定UItableview高度时要增加高度,而“发现”是自适应高度,则需要在分别初始化scrollview中的四个UItableview时,将UItableview的高度从mainscreenheight变成mainscreenheight-64-49(64是导航栏的高度,49是tabbar的高度)

uitabbarcontroller的代码如下。

- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor=[UIColor whiteColor];
//    self.edgesForExtendedLayout=UIRectEdgeNone;ViewController *v1=[[ViewController alloc]init];v1.tabBarItem.title=@"首页";v1.tabBarItem.image=[UIImage imageNamed:@"1"];UINavigationController *firstNav=[[UINavigationController alloc]initWithRootViewController:v1];[self addChildViewController:firstNav];TwoViewController *v2=[[TwoViewController alloc]init];v2.tabBarItem.title=@"发现";v2.tabBarItem.image=[UIImage imageNamed:@"3"];
//    UINavigationController *SecondNav=[[UINavigationController alloc]initWithRootViewController:v2];
//    [self addChildViewController:SecondNav];[self addChildViewController:v2];MyViewController *v3=[[MyViewController alloc]init];v3.tabBarItem.title=@"我";v3.tabBarItem.image=[UIImage imageNamed:@"4"];UINavigationController *ThirdNav=[[UINavigationController alloc]initWithRootViewController:v3];[self addChildViewController:ThirdNav];  //初次进入程序,title不能显示??要再点回来才可以}

主要是介绍“发现”页面的实现

“发现”页面命名为TwoViewController,隐藏navigationBar。所以在uitabbarcontroller中创建"发现"页面时没用到UINavigationController, 在TwoViewController.m中需要加上self.navigationController.navigationBar.hidden=YES;语句

  

这个页面用到横向滑动的UIscrollview ,一共包含四个页面

在页面相应位置初始化四个UIbutton,分别是“视频”、“音乐”、“早午茶”、“猜你喜欢”,代码如下

self.videoBtn=[[UIButton alloc]initWithFrame:CGRectMake(0, 30, mainscreenwidth/4, 20)];[self.videoBtn setTitle:@"视频" forState:UIControlStateNormal];[self.videoBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];  //默认被选中[self.videoBtn addTarget:self action:@selector(videoBtnClick) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:self.videoBtn];self.musicBtn=[[UIButton alloc]initWithFrame:CGRectMake(mainscreenwidth/4, 30, mainscreenwidth/4, 20)];[self.musicBtn setTitle:@"音乐" forState:UIControlStateNormal];[self.musicBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //默认没被选中[self.musicBtn addTarget:self action:@selector(musicBtnClick) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:self.musicBtn];self.dinnerBtn=[[UIButton alloc]initWithFrame:CGRectMake(mainscreenwidth/4*2, 30, mainscreenwidth/4, 20)];[self.dinnerBtn setTitle:@"早午茶" forState:UIControlStateNormal];[self.dinnerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //默认没被选中[self.dinnerBtn addTarget:self action:@selector(dinnerBtnClick) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:self.dinnerBtn];self.likeBtn=[[UIButton alloc]initWithFrame:CGRectMake(mainscreenwidth/4*3, 30, mainscreenwidth/4, 20)];[self.likeBtn setTitle:@"猜你喜欢" forState:UIControlStateNormal];[self.likeBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  //默认没被选中[self.likeBtn addTarget:self action:@selector(likeBtnClick) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:self.likeBtn];

为每个UIbutton定义触发后事件

-(void)videoBtnClick{self.slideLab.frame=CGRectMake(20, 52, mainscreenwidth/4-40, 2);  //横条滑动[self.videoBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];[self.musicBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.dinnerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.likeBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:0.3];[self.scrollView setContentOffset:CGPointMake(mainscreenwidth*0, 0)];[UIView commitAnimations];
}-(void)musicBtnClick{self.slideLab.frame=CGRectMake(20+mainscreenwidth/4, 52, mainscreenwidth/4-40, 2);//横条滑动[self.videoBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.musicBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];[self.dinnerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.likeBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:0.3];[self.scrollView setContentOffset:CGPointMake(mainscreenwidth*1, 0)];[UIView commitAnimations];
}-(void)dinnerBtnClick{self.slideLab.frame=CGRectMake(20+2*mainscreenwidth/4, 52, mainscreenwidth/4-40, 2);//横条滑动[self.videoBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.musicBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.dinnerBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];[self.likeBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:0.3];[self.scrollView setContentOffset:CGPointMake(mainscreenwidth*2, 0)];[UIView commitAnimations];
}-(void)likeBtnClick{self.slideLab.frame=CGRectMake(20+3*mainscreenwidth/4, 52, mainscreenwidth/4-40, 2);//横条滑动[self.videoBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.musicBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.dinnerBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[self.likeBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];[UIView beginAnimations:nil context:nil];[UIView setAnimationDuration:0.3];[self.scrollView setContentOffset:CGPointMake(mainscreenwidth*3, 0)];[UIView commitAnimations];
}

然后初始化UIbutton下面起到显示引导作用的横条

self.slideLab=[[UILabel alloc]init];self.slideLab.frame=CGRectMake(20, 52, mainscreenwidth/4-40, 2);self.slideLab.backgroundColor=[UIColor orangeColor];[self.view addSubview:self.slideLab]; 

接下来初始化横向滑动的UIscrollview

self.scrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 55, mainscreenwidth, mainscreenheight)];self.scrollView.delegate=self;self.scrollView.contentSize=CGSizeMake(mainscreenwidth*4, mainscreenheight);self.scrollView.pagingEnabled=YES;   //一开始写成了scrollenabled ,然后出现一次会滑动很多页的情况,修改成pagingEnabled之后,变为一次滑动一页self.scrollView.bounces=NO;self.scrollView.showsVerticalScrollIndicator=NO;self.scrollView.showsHorizontalScrollIndicator=NO;[self.view addSubview:self.scrollView];

接下来是滑动scrollview时页面的跳转方法

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{CGFloat offset=self.scrollView.contentOffset.x;int page=(offset+mainscreenwidth/2)/mainscreenwidth;self.pageControl.currentPage=page;if(self.pageControl.currentPage==0){[self videoBtnClick];}else if (self.pageControl.currentPage==1){[self musicBtnClick];}else if (self.pageControl.currentPage==2){[self dinnerBtnClick];}else{[self likeBtnClick];}
}

接下来依次往UIscrollview中添加tableview

self.videoTV=[[UITableView alloc]initWithFrame:CGRectMake(0, 2, mainscreenwidth, mainscreenheight-64-49) style:UITableViewStylePlain];self.videoTV.delegate=self;self.videoTV.dataSource=self;[self.scrollView addSubview:self.videoTV];self.musicTV=[[UITableView alloc]initWithFrame:CGRectMake(mainscreenwidth, 2, mainscreenwidth, mainscreenheight-64-49) style:UITableViewStylePlain];self.musicTV.delegate=self;self.musicTV.dataSource=self;[self.scrollView addSubview:self.musicTV];self.dinnerTV=[[UITableView alloc]initWithFrame:CGRectMake(mainscreenwidth*2, 2, mainscreenwidth, mainscreenheight-64-49) style:UITableViewStylePlain];self.dinnerTV.delegate=self;self.dinnerTV.dataSource=self;self.dinnerTV.separatorStyle=UITableViewCellSeparatorStyleNone;[self.scrollView addSubview:self.dinnerTV];//解决点击按键时屏幕跳动的问题self.dinnerTV.estimatedRowHeight=0;self.dinnerTV.estimatedSectionFooterHeight=0;self.dinnerTV.estimatedSectionHeaderHeight=0;self.likeTV=[[UITableView alloc]initWithFrame:CGRectMake(mainscreenwidth*3, 2, mainscreenwidth, mainscreenheight-64-49) style:UITableViewStylePlain];self.likeTV.delegate=self;self.likeTV.dataSource=self;[self.scrollView addSubview:self.likeTV];self.pageControl=[[UIPageControl alloc]initWithFrame:CGRectMake(50, mainscreenheight-30-50, 100, 30)];self.pageControl.currentPage=0;self.pageControl.numberOfPages=4;self.pageControl.hidden=YES;[self.view addSubview:self.pageControl];

在viewDidLoad方法中调用 setupArray方法,依次为数组赋值

-(void)setupArray{VideoModel *videoM=[[VideoModel alloc]init];videoM.photoName=@"123.jpg";videoM.Name=@"Peter Elson";videoM.detail=@"Peter Elson (1947 – 1998),英国科幻小说插画师,他的许多作品对后来的太空游戏创作产生了很大的影响,整整影响了一代科幻插图画家和概念艺术家。";CommentModel *commentModel1=[[CommentModel alloc]init];commentModel1.commentA=@"据了解";commentModel1.commentB=@"博客";commentModel1.commentDetail=@"胜利路南";videoM.commentModelArray=[[NSArray alloc]initWithObjects:commentModel1, nil];VideoModel *videoM2=[[VideoModel alloc]init];videoM2.photoName=@"124.jpg";videoM2.Name=@"美丽的黄昏";videoM2.detail=@"三个月前,不顾朋友、家人、同事反对,毅然决然地做了一件想了三年的事——记录这个时代的建筑者。";CommentModel *commentModel2=[[CommentModel alloc]init];commentModel2.commentA=@"姜汁";commentModel2.commentB=@"普洱";commentModel2.commentDetail=@"是你每次";videoM2.commentModelArray=[[NSArray alloc]initWithObjects:commentModel2,commentModel1, nil];VideoModel *videoM3=[[VideoModel alloc]init];videoM3.photoName=@"125.jpg";videoM3.Name=@"MusicWars";videoM3.detail=@"电影版《唐顿庄园》北美正式定档2019年9月20日!其他部分地区将于9月13日上线!电视剧版的演员Maggie Smith、Hugh Bonneville、Michelle Dockery、Elizabeth McGovern等人将确定回归影版";CommentModel *commentModel3=[[CommentModel alloc]init];commentModel3.commentA=@"欧派";commentModel3.commentB=@"思想";commentModel3.commentDetail=@"主持稿";videoM3.commentModelArray=[[NSArray alloc]initWithObjects:commentModel1,commentModel3,commentModel2,nil];VideoModel *videoM4=[[VideoModel alloc]init];videoM4.photoName=@"126.jpg";videoM4.Name=@"艾薇儿Avril";videoM4.detail=@"艾薇儿Avril回归新单《Head Above Water》歌词版超清MV大首播!这首歌曲是艾薇儿Avril患病期间卧床写的,艾薇儿说:我已经接受了死亡,可以感受到我的身体正在关闭,就像溺水,我正在水里面,很需要赶快上去吸一口气。整首歌都是记录她患病那些日子的感受!";CommentModel *commentModel4=[[CommentModel alloc]init];commentModel4.commentA=@"皮特";commentModel4.commentB=@"如律";commentModel4.commentDetail=@"大考卷下半年";videoM4.commentModelArray=[[NSArray alloc]initWithObjects:commentModel1,commentModel3,commentModel4,nil];VideoModel *videoM5=[[VideoModel alloc]init];videoM5.photoName=@"127.jpg";videoM5.Name=@"伪命题";videoM5.detail=@"随着沪深股市持续下跌,外资抄底A股的声音又出现了。其实,此前股市下跌后如果出现大幅上涨行情,总有某某资金抄底的声音,比如险资、比如外资。";CommentModel *commentModel5=[[CommentModel alloc]init];commentModel5.commentA=@"麦炒饼VS炒面";commentModel5.commentB=@"坐标系";commentModel5.commentDetail=@"突然好怀念吧";videoM5.commentModelArray=[[NSArray alloc]initWithObjects:commentModel1,commentModel4,commentModel2,nil];self.videoArray=[[NSMutableArray alloc]initWithObjects:videoM,videoM2,videoM3,videoM4,videoM5, nil];MusicModel *musicM=[[MusicModel alloc]init];musicM.PicName=@"01.jpg";musicM.userName=@"YUE XUAN";musicM.titleName=@"好好";musicM.userPhotoName=@"125.jpg";musicM.musicName=@"好好";musicM.detailName=@"《好好(想把你写成一首歌)》是由阿信作词,冠佑、阿信作曲、五月天演唱的歌曲,收录在五月天第9张专辑《自传》中。于2016年10月11日作为新海诚动漫电影《你的名字》的台湾地区宣传曲。";MusicModel *musicM2=[[MusicModel alloc]init];musicM2.PicName=@"0.jpeg";musicM2.userName=@"AwLi";musicM2.titleName=@"Peter Elson ";musicM2.userPhotoName=@"126.jpg";musicM2.musicName=@"像我这样的人";musicM2.detailName=@"小时候的毛不易觉得自己是个非常与众不同的人,但随着年龄的增长,毛不易发现自己可能并没有那么特别,对于那种泯然众人的感觉让他觉得很难受,他觉得很不甘心 ,却又无能为力。在毛不易面临大学毕业的时,他试图逃离现状,又不知去往何处。2016年,毛不易在杭州地方医院实习时,他开始提笔写歌,他把这样的自己写进了歌曲《像我这样的人》中。";MusicModel *musicM3=[[MusicModel alloc]init];musicM3.PicName=@"02";musicM3.userName=@"MOWEN";musicM3.titleName=@"好久不见";musicM3.userPhotoName=@"127.jpg";musicM3.musicName=@"好久不见";musicM3.detailName=@"《好久不见》是翻唱陈奕迅的粤语专辑《What's Going On...?》中的歌曲《不如不见》,《不如不见》由创作了《十年》的陈小霞作曲,请到作词人施立填上国语歌词,来描述期望和旧情人重逢,可以淡淡说声好久不见的意境,词填得不温不火,似只是在喃喃述说一个再也平常不过的爱情故事,适合陈奕迅淡定落寞却又充满沧桑沙哑的声音,谱写出一首凄美的情歌";MusicModel *musicM4=[[MusicModel alloc]init];musicM4.PicName=@"03.jpeg";musicM4.userName=@"yanY";musicM4.titleName=@"等你下课 ";musicM4.userPhotoName=@"128.jpg";musicM4.musicName=@"等你下课";musicM4.detailName=@"2017年忙碌于巡回演唱会的周杰伦,心里一直惦记着不想让歌迷等新歌等太久。周杰伦趁着演唱会的庆功宴空档写歌,当工作人员在庆功宴上放松时,他灵感来了就回到自己的房间里,拿起吉他轻刷旋律写下这首《等你下课》,词曲皆出自周杰伦之手,一气呵成。";MusicModel *musicM5=[[MusicModel alloc]init];musicM5.PicName=@"04.jpg";musicM5.userName=@"往事随风";musicM5.titleName=@"告白气球";musicM5.userPhotoName=@"124.jpg";musicM5.musicName=@"告白气球";musicM5.detailName=@"词作者方文山为周杰伦创作了《印地安老斑鸠》之后,在《周杰伦的睡前故事》这张专辑里为周杰伦量身打造了一首甜美浪漫曲风的歌曲——《告白气球》。该歌曲灵感来源于法国的美景,觉得应该来一首《简单爱》类似的歌曲创作,回顾一下以前那种对于初恋、小清新的感觉。在创作过程中周杰伦一直保持着童心未泯的心态与方文山一起合作,自己坦言这首歌是专辑里面,写得最简单的,最好写的。";self.musicArray=[[NSMutableArray alloc]initWithObjects:musicM,musicM2,musicM3,musicM4,musicM5, nil];self.musicNameArray=[[NSMutableArray alloc]initWithObjects:@"好好",@"像我这样的人",@"好久不见",@"等你下课",@"告白气球", nil];DinnerModel *dinnerM=[[DinnerModel alloc]init];dinnerM.userIconName=@"棒棒糖";dinnerM.userName=@"棒棒糖";dinnerM.detail=@"1758年,闻名世界的棒棒糖(lollipop)的发明人恩里克·伯纳特·丰利亚多萨,首次推出这种带棍的糖果,结果使一家几乎经营不下去的糖果公司扭亏为盈。";dinnerM.PhotoNameArray=@[@"12344.jpg",@"123445.jpg"];DinnerModel *dinnerM2=[[DinnerModel alloc]init];dinnerM2.userIconName=@"冰淇凌";dinnerM2.userName=@"冰淇淋";dinnerM2.detail=@"将近800年以前,冰淇淋源于中国。在元朝的时候,一位精明的食品店商人突发奇想,他尝试着在冰中添加一些蜜糖、牛奶和珍珠粉,结果,制成了世界上最早的冰淇淋。";dinnerM2.PhotoNameArray=@[];
//    dinnerM2.PhotoNameArray=[[NSArray alloc]initWithObjects:@"12355.jpg",@"123556.jpg",@"123557.jpg",@"123558.jpg",nil];DinnerModel *dinnerM3=[[DinnerModel alloc]init];dinnerM3.userIconName=@"沙拉";dinnerM3.userName=@"沙拉";dinnerM3.detail=@"主要有三类,水果沙拉、蔬菜沙拉、其他沙拉。由绿色有叶生菜制成的一道菜,常加有萝卜、黄瓜或西红柿,并加调味品食用。";dinnerM3.PhotoNameArray=@[@"123559.jpg",@"1235510.jpg"];DinnerModel *dinnerM4=[[DinnerModel alloc]init];dinnerM4.userIconName=@"薯条可乐";dinnerM4.userName=@"薯条可乐";dinnerM4.detail=@"薯条的英文是“Chips”,美国人称之为“French Fries”.";dinnerM4.PhotoNameArray=@[@"1235511.jpg",@"1235512.jpg",@"1235513",@"1235514.jpg"];DinnerModel *dinnerM5=[[DinnerModel alloc]init];dinnerM5.userIconName=@"甜甜圈";dinnerM5.userName=@"甜甜圈";dinnerM5.detail=@"现在的甜甜圈在美国还是最为受欢迎的一种甜品,任何一个糕点店铺或快餐店都有出售。从5岁儿童到75岁老人都对它有着一致的热爱。";dinnerM5.PhotoNameArray=@[@"1235515.jpg"];self.dinnerArray=[[NSMutableArray alloc]initWithObjects:dinnerM,dinnerM2,dinnerM3,dinnerM4,dinnerM5, nil];
}

依次完成四个子页面的布局。

首先自定义“视频”子页面的videotableViewcell 。

定义一个videoModel

#import <Foundation/Foundation.h>@interface VideoModel : NSObject
@property (nonatomic,strong) NSString *photoName;
@property (nonatomic,strong) NSString *Name;
@property (nonatomic,strong) NSString *detail;
@property (nonatomic,strong) NSArray *commentModelArray; //评论数组@end 

页面中,四个按键从左到右依次是转发,收藏,点赞和评论,点击后可以实现相应功能,四个按键添加在另外定义的一个view中,命名为operationmenu 。 评论区域也另外定义一个view,命名为commentview

先完成operationmenu 的布局  , OperationMenu.h文件定义如下

#import <UIKit/UIKit.h>
#import <Social/Social.h>
#import "VideoModel.h"@protocol OperationMenuClick <NSObject>   //声明协议
-(void) didClickShare;
@end@interface OperationMenu : UIView
@property (nonatomic,strong) UIButton *shareBtn;
@property (nonatomic,strong) UIButton *collectionBtn;
@property (nonatomic,strong) UIButton *likeBtn;
@property (nonatomic,strong) UILabel *likeNumLabel;
@property (nonatomic,strong) UIButton *commentBtn;
@property (nonatomic,strong) UILabel *commentNumLabel;
@property (nonatomic,weak) id <OperationMenuClick> delegate;@property (nonatomic,copy) void  (^commentClick)(void);  //block@end

因为点击具体cell的转发按键shareBtn,转发的是具体cell的内容,所以声明了一个OperationMenuClick协议,在shareBtn的按键点击处理事件中写上 [self.delegate didClickShare];  cell调用该协议,实现该协议中定义的didClickShare功能。cell中的OperationMenuClick协议相关部分的代码如下

-(void)didClickShare{//文字加图片分享NSString *textToShare = self.detailLabel.text;UIImage *imageToShare=[self getJPEGImagerImg:self.photoImg.image];  //压缩图片
//    UIImage *imageToShare = [UIImage imageNamed:@"btn-share-link"];NSURL *urlToShare = [NSURL URLWithString:@"http://www.baidu.com"];NSArray *activityItems = @[textToShare, imageToShare, urlToShare];UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:nil];// 排除(UIActivityTypeAirDrop)AirDrop 共享、(UIActivityTypePostToFacebook)FacebookactivityVC.excludedActivityTypes = @[UIActivityTypePostToFacebook, UIActivityTypeAirDrop];[self.delegate didShare:activityVC];}#pragma mark - 压缩一张图片 最大宽高1280 类似于微信算法
- (UIImage *)getJPEGImagerImg:(UIImage *)image{CGFloat oldImg_WID = image.size.width;CGFloat oldImg_HEI = image.size.height;//CGFloat aspectRatio = oldImg_WID/oldImg_HEI;//宽高比if(oldImg_WID > KCompressibilityFactor || oldImg_HEI > KCompressibilityFactor){//超过设置的最大宽度 先判断那个边最长if(oldImg_WID > oldImg_HEI){//宽度大于高度oldImg_HEI = (KCompressibilityFactor * oldImg_HEI)/oldImg_WID;oldImg_WID = KCompressibilityFactor;}else{oldImg_WID = (KCompressibilityFactor * oldImg_WID)/oldImg_HEI;oldImg_HEI = KCompressibilityFactor;}}UIImage *newImg = [self imageWithImage:image scaledToSize:CGSizeMake(oldImg_WID, oldImg_HEI)];NSData *dJpeg = nil;if (UIImagePNGRepresentation(newImg)==nil) {dJpeg = UIImageJPEGRepresentation(newImg, 0.5);}else{dJpeg = UIImagePNGRepresentation(newImg);}return [UIImage imageWithData:dJpeg];
}

因为转发提示框是在TwoViewController中展示,所以在cell中还需要声明一个ShareClick协议,通过该协议定义的方法传递当前转发提示框

@protocol ShareClick <NSObject>   //声明协议
-(void) didShare:(UIActivityViewController *)activityVC;
@end

TwoViewController调用该协议,实现该协议中定义的didShare方法,TwoViewController中的ShareClick协议相关部分的代码如下

-(void) didShare:(UIActivityViewController *)activityVC{   //实现协议定义的方法[self presentViewController:activityVC animated:YES completion:nil];
}

因为点击具体cell的评论按键commentBtn,评论的是具体cell的内容,所以

通过  @property (nonatomic,copy) void  (^commentClick)(void);  //block

声明了一个block块,在commentBtn的按键点击处理事件中写上

-(void)comment{
    if(self.commentClick){   //block
        self.commentClick();
    }

cell中commentClick块相关部分的代码如下

[self.operationMenu setCommentClick:^{if([weakSelf.delegate respondsToSelector:@selector(didClickComment:)]){[weakSelf.delegate didClickComment:weakSelf];  //调用协议的方法,传递参数值weakSelf}}];

因为实际的回复内容是从键盘输入,所以实际的回复内容是在TwoViewController中获取,所以在cell中还需要声明一个ShareClick协议,通过该协议定义的方法传递当前cell

@protocol ShareClick <NSObject>   //声明协议
-(void) didClickComment:(VideoTableViewCell *)cell;
@end

TwoViewController调用该协议,实现该协议中定义的didClickComment方法,TwoViewController中的ShareClick协议相关部分的代码如下

-(void)didClickComment:(VideoTableViewCell *)cell{   //实现协议定义的方法//协议传递cell值,获取cell然后执行下面的操作[self.textField becomeFirstResponder];self.currentIndexPath=[self.videoTV indexPathForCell:cell];   //获取当前行[self adjust];
}

OperationMenu.m文件定义如下

#import "OperationMenu.h"
#import "UIView+SDAutoLayout.h"@implementation OperationMenu-(instancetype)initWithFrame:(CGRect)frame{self=[super initWithFrame:frame];if(self){[self createUI];}return self;
}-(void)createUI{self.shareBtn=[UIButton buttonWithType:UIButtonTypeCustom];[self.shareBtn setImage:[UIImage imageNamed:@"item-btn-share-black"] forState:UIControlStateNormal];[self.shareBtn addTarget:self action:@selector(share) forControlEvents:UIControlEventTouchUpInside];[self addSubview:self.shareBtn];self.collectionBtn=[UIButton buttonWithType:UIButtonTypeCustom];[self.collectionBtn setImage:[UIImage imageNamed:@"item-btn-like-black"] forState:UIControlStateNormal];[self.collectionBtn addTarget:self action:@selector(collection:) forControlEvents:UIControlEventTouchUpInside];[self addSubview:self.collectionBtn];self.likeBtn=[UIButton buttonWithType:UIButtonTypeCustom];[self.likeBtn setImage:[UIImage imageNamed:@"item-btn-thumb-black"] forState:UIControlStateNormal];[self.likeBtn addTarget:self action:@selector(like:) forControlEvents:UIControlEventTouchUpInside];[self addSubview:self.likeBtn];self.likeNumLabel=[[UILabel alloc]init];self.likeNumLabel.text=@"5";self.likeNumLabel.textColor=[UIColor lightGrayColor];[self addSubview:self.likeNumLabel];self.commentBtn=[UIButton buttonWithType:UIButtonTypeCustom];[self.commentBtn setImage:[UIImage imageNamed:@"item-btn-comment-black"] forState:UIControlStateNormal];[self.commentBtn addTarget:self action:@selector(comment) forControlEvents:UIControlEventTouchUpInside];[self addSubview:self.commentBtn];self.commentNumLabel=[[UILabel alloc]init];self.commentNumLabel.textColor=[UIColor lightGrayColor];[self addSubview:self.commentNumLabel];self.shareBtn.sd_layout.leftSpaceToView(self, 2).topSpaceToView(self, 2).widthIs(35).bottomEqualToView(self);self.collectionBtn.sd_layout.leftSpaceToView(self.shareBtn, 15).topSpaceToView(self, 2).widthIs(35).bottomEqualToView(self);self.likeBtn.sd_layout.leftSpaceToView(self.collectionBtn, 15).topSpaceToView(self, 2).widthIs(35).bottomEqualToView(self);self.likeNumLabel.sd_layout.leftSpaceToView(self.likeBtn, 0).topSpaceToView(self, 2).widthIs(15).bottomEqualToView(self);self.commentBtn.sd_layout.leftSpaceToView(self.likeNumLabel, 10).topSpaceToView(self, 2).widthIs(35).bottomEqualToView(self);self.commentNumLabel.sd_layout.leftSpaceToView(self.commentBtn, 0).topSpaceToView(self, 2).widthIs(20).bottomEqualToView(self);[self setupAutoWidthWithRightView:self.commentNumLabel rightMargin:10];
}-(void)share{[self.delegate didClickShare];
}-(void)collection:(UIButton *)sender{    //收藏状态sender.selected=!sender.selected;   //取反状态if(sender.selected==YES){[self.collectionBtn setImage:[UIImage imageNamed:@"icon-bookmark-v32"] forState:UIControlStateNormal];}else{[self.collectionBtn setImage:[UIImage imageNamed:@"item-btn-like-black"] forState:UIControlStateNormal];}
}-(void)like:(UIButton *)sender{   //点赞状态sender.selected=!sender.selected;    //取反状态int numb=[self.likeNumLabel.text intValue];if(sender.selected==YES){    //选中状态[self.likeBtn setImage:[UIImage imageNamed:@"icon-zan"] forState:UIControlStateNormal];numb=numb+1;NSString *num=[NSString stringWithFormat:@"%d",numb];self.likeNumLabel.text=num;}else{    //取消状态[self.likeBtn setImage:[UIImage imageNamed:@"item-btn-thumb-black"] forState:UIControlStateNormal];numb=numb-1;NSString *num=[NSString stringWithFormat:@"%d",numb];self.likeNumLabel.text=num;}
}-(void)comment{if(self.commentClick){   //blockself.commentClick();}
}

然后完成commentview 的布局

因为点击具体一条评论,回复的是具体评论者,所以声明了一个commentProtocol协议,在每一条评论label的点击事件中写上[self.delegate commentClick:commentTo];   通过该协议定义的方法传递被回复者的名称

cell调用该协议,实现该协议中定义的commentClick方法。cell中的commentProtocol协议相关部分的代码如下

-(void)commentClick:(NSString *)string{self.isReplying=YES;[self.delegate didComment:self andString:string];
}

因为实际的回复内容是从键盘输入,所以实际的回复内容是在TwoViewController中获取,所以在cell中还需要声明一个ShareClick协议,通过该协议定义的方法传递当前cell以及被回复者的名称

@protocol ShareClick <NSObject>   //声明协议
-(void) didComment:(VideoTableViewCell *)cell andString:(NSString*)string;
@end

TwoViewController调用该协议,实现该协议中定义的didcomment方法,TwoViewController中的ShareClick协议相关部分的代码如下

-(void)didComment:(VideoTableViewCell *)cell andString:(NSString*)string{[self.textField becomeFirstResponder];self.currentIndexPath=[self.videoTV indexPathForCell:cell];   //获取当前行self.commentTo=string;[self adjust];self.isReplyingComment=cell.isReplying;
}

commentview.h 声明如下  在.h文件中暴露一个setcommentview方法,即可实现对commentview赋值

#import <UIKit/UIKit.h>
#import "CommentModel.h"@protocol commentProtocol<NSObject>
-(void)commentClick:(NSString *)string;
@end@interface CommentView : UIView@property(nonatomic,strong)UIImageView *backGroundIV;
@property (nonatomic,strong) NSArray *commentArray; //存放评论model
@property (nonatomic,strong) NSMutableArray *commentItemsArray;
@property (nonatomic,weak) id <commentProtocol> delegate;-(void)setCommentView:(NSArray *)commentModelArray;   //cell中调用此方法,完成对commentview的赋值@end

commentview.m 声明如下

#import "CommentView.h"
#import "UIView+SDAutoLayout.h"@implementation CommentView
- (instancetype)initWithFrame:(CGRect)frame{self=[super initWithFrame:frame];if(self){[self createUI];self.commentItemsArray=[[NSMutableArray alloc]init];}return self;
}-(void)createUI{self.backGroundIV=[[UIImageView alloc]init];self.backGroundIV.image=[[[UIImage imageNamed:@"LikeCmtBg"]stretchableImageWithLeftCapWidth:40 topCapHeight:30]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];self.backGroundIV.backgroundColor=[UIColor clearColor];[self addSubview:self.backGroundIV];self.backGroundIV.sd_layout.spaceToSuperView(UIEdgeInsetsMake(0, 0, 0, 0));
}- (void)setCommentArray:(NSArray *)commentArray{   //重写set方法_commentArray=commentArray;long originalLabelsCount=self.commentItemsArray.count; //初始评论数long needsToAddCount=commentArray.count > originalLabelsCount? (commentArray.count-originalLabelsCount):0;  //新增的评论数量//添加labelfor(int i=0;i<needsToAddCount;i++){UILabel *label=[[UILabel alloc]init];[self addSubview:label];[self.commentItemsArray addObject:label];}//为label赋值for(int i=0;i<commentArray.count;i++){CommentModel *commentModel=commentArray[i];   //取出modelUILabel *label=self.commentItemsArray[i];if(commentModel.attributedContent==nil)label.attributedText=[self generateAttributedStringWithCommentItemModel:commentModel];   //根据评论model为label赋值}
}- (NSMutableAttributedString *)generateAttributedStringWithCommentItemModel:(CommentModel *)commentModel{NSString *tex=commentModel.commentA;if(commentModel.commentB.length){tex=[tex stringByAppendingString:[NSString  stringWithFormat:@"回复%@",commentModel.commentB]];  // A 回复 B}tex=[tex stringByAppendingString:[NSString  stringWithFormat: @": %@",commentModel.commentDetail]];  // A 回复 B :----NSMutableAttributedString *str=[[NSMutableAttributedString alloc]initWithString:tex];[str addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:[tex rangeOfString:commentModel.commentA]];if(commentModel.commentB){[str addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:[tex rangeOfString:commentModel.commentB]];}  //修改部分字体颜色return str;
}-(void)setCommentView:(NSArray *)commentModelArray{self.commentArray=commentModelArray;   //self.commentArray=  调用- (void)setCommentArray:(NSArray *)commentArray方法实现赋值if(self.commentItemsArray.count){[self.commentItemsArray enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger idx, BOOL *  stop) {[label sd_clearAutoLayoutSettings];  //重用时先隐藏所有的评论labellabel.hidden=YES;}];}if(self.commentArray.count==0){self.fixedWidth=@(0);  //固定宽度self.fixedHeight=@(0); //固定高度return;}else{self.fixedHeight=nil;  //取消固定高度self.fixedWidth=nil;   //取消固定宽度}UIView *lastTopView=nil;for(int i=0;i<self.commentArray.count;i++){UILabel *label=(UILabel *)self.commentItemsArray[i];   //取出前面已经赋值过的labellabel.hidden=NO;label.sd_layout.leftEqualToView(self).rightSpaceToView(self, 2).topSpaceToView(lastTopView, 1)   // 每个label相对于上一个label设置距离.autoHeightRatio(0);label.isAttributedContent=YES;lastTopView=label;//为每一个评论label加上手势识别UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(addComment:)];label.userInteractionEnabled=YES;[label addGestureRecognizer:tap];label.tag=i;}[self setupAutoHeightWithBottomView:lastTopView bottomMargin:6];
}-(void)addComment:(UITapGestureRecognizer *)sender{CommentModel *model=self.commentArray[sender.view.tag];   //获取点击的当前label所在modelNSString *commentTo=model.commentA;[self.delegate commentClick:commentTo];  //delegate传递model的commentA参数
}

CommentView和OperationMenu的界面布局基本完成,然后进行VideoTableViewCell的布局

VideoTableViewCell布局部分代码如下

self.photoImg=[[UIImageView alloc]init];[self.contentView addSubview:self.photoImg];self.nameLabel=[[UILabel alloc]init];self.nameLabel.font=[UIFont systemFontOfSize:24];[self.contentView addSubview:self.nameLabel];self.detailLabel=[[UILabel alloc]init];self.detailLabel.textColor=[UIColor lightGrayColor];[self.contentView addSubview:self.detailLabel];__weak typeof (self)weakSelf=self;self.operationMenu=[[OperationMenu alloc]init];[self.contentView addSubview:self.operationMenu];self.operationMenu.delegate=self;[self.operationMenu setCommentClick:^{if([weakSelf.delegate respondsToSelector:@selector(didClickComment:)]){[weakSelf.delegate didClickComment:weakSelf];  //调用协议的方法,传递参数值weakSelf}}];self.commentView=[[CommentView alloc]init];[self.contentView addSubview:self.commentView];self.commentView.delegate=self;self.photoImg.sd_layout.rightSpaceToView(self.contentView, 10).leftSpaceToView(self.contentView, 10).topSpaceToView(self.contentView, 15).heightIs(160);self.nameLabel.sd_layout.widthIs(150).leftEqualToView(self.photoImg).topSpaceToView(self.photoImg, 15).heightIs(20);self.detailLabel.sd_layout.widthRatioToView(self.photoImg, 1).leftEqualToView(self.photoImg).topSpaceToView(self.nameLabel, 20).autoHeightRatio(0);self.operationMenu.sd_layout.leftEqualToView(self.photoImg).topSpaceToView(self.detailLabel, 10).heightIs(45);self.commentView.sd_layout.leftSpaceToView(self.contentView, 15).rightSpaceToView(self.contentView, 15).topSpaceToView(self.operationMenu, 0);[self setupAutoHeightWithBottomView:self.commentView bottomMargin:20];

在.h文件中暴露一个setModel方法,TwoViewController中调用该方法,即可实现对cell赋值

-(void)setModel:(VideoModel *) videoModel{self.photoImg.image=[UIImage imageNamed:videoModel.photoName];self.nameLabel.text=videoModel.Name;self.detailLabel.text=videoModel.detail;self.operationMenu.commentNumLabel.text=[NSString stringWithFormat:@"%lu", (unsigned long)videoModel.commentModelArray.count];  //评论数由commentModelArray的数目决定[self.commentView setCommentView:videoModel.commentModelArray];
}

TwoViewController中与文本输入textfield有关代码如下

- (void)viewDidLoad {[self setupTextField];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardNotification:) name:UIKeyboardWillChangeFrameNotification object:nil];
}-(void)setupTextField{self.textField=[[UITextField alloc]init];self.textField.returnKeyType=UIReturnKeyDone;self.textField.delegate=self;self.textField.backgroundColor=[UIColor whiteColor];self.textField.frame=CGRectMake(0, [UIScreen mainScreen].bounds.size.height, self.view.width_sd, textFieldH);[[UIApplication sharedApplication].keyWindow addSubview:self.textField];[self.textField becomeFirstResponder];[self.textField resignFirstResponder];
}-(void)viewWillDisappear:(BOOL)animated{[self.textField resignFirstResponder];}-(void)dealloc{[self.textField removeFromSuperview];[[NSNotificationCenter defaultCenter] removeObserver:self];
}-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ //开始滑动页面时,收回键盘[self.textField resignFirstResponder];
}-(BOOL)textFieldShouldReturn:(UITextField *)textField{if(textField.text.length){[textField resignFirstResponder];VideoModel *model=self.videoArray[self.currentIndexPath.row];  //取出当前modelNSMutableArray *temp=[[NSMutableArray alloc]init];[temp addObjectsFromArray:model.commentModelArray];  //添加当前model的所有评论数组CommentModel *commentModel=[[CommentModel alloc]init];commentModel.commentA=@"K";if(self.isReplyingComment){   //回复他人评论commentModel.commentDetail=textField.text;commentModel.commentB=self.commentTo;self.isReplyingComment=NO;}else{commentModel.commentDetail=textField.text;}[temp addObject:commentModel];   //添加新的评论数组model.commentModelArray=[temp copy];   //更新得到新的commentModelArray[self.videoTV reloadRowsAtIndexPaths:@[self.currentIndexPath] withRowAnimation:UITableViewRowAnimationNone];   //刷新当前行self.textField.text=@"";return YES;}return NO;
}-(void)keyboardNotification:(NSNotification *)notification{NSDictionary *dic=notification.userInfo;CGRect rect=[dic[@"UIKeyboardFrameEndUserInfoKey"]CGRectValue];CGRect textFieldRect =CGRectMake(0, rect.origin.y-textFieldH, rect.size.width, textFieldH);if(rect.origin.y==[UIScreen mainScreen].bounds.size.height){textFieldRect=rect;}[UIView animateWithDuration:0.25 animations:^{self.textField.frame=textFieldRect;}];CGFloat h=rect.size.height+textFieldH;if(self.keyboardHeight!=h){self.keyboardHeight=h;[self adjust];}
}-(void)adjust{UIWindow *win=[UIApplication sharedApplication].keyWindow;UITableViewCell *cell=[self.videoTV cellForRowAtIndexPath:self.currentIndexPath];CGRect rect=[cell.superview convertRect:cell.frame toView:win];CGFloat de=CGRectGetMaxY(rect)-(win.bounds.size.height-self.keyboardHeight);CGPoint offset=self.videoTV.contentOffset;offset.y+=de;if(offset.y<0){offset.y=0;}[self.videoTV setContentOffset:offset animated:YES];
}

至此,“视频”界面基本完成

接下来进行“音乐”界面的布局 ,首先自定义“音乐”子页面的musictableViewcell 。

定义一个musicModel

#import <Foundation/Foundation.h>@interface MusicModel : NSObject
@property (nonatomic,strong) NSString *PicName;
@property (nonatomic,strong) NSString *userName;
@property (nonatomic,strong) NSString *userPhotoName;
@property (nonatomic,strong) NSString *musicName;
@property (nonatomic,strong) NSString *titleName;
@property (nonatomic,strong) NSString *detailName;
@end

接下来是MusicTableViewCell的布局代码。因为要实现音乐播放的功能 , 所以用到了AVAudioPlayer ,需要导入#import <AVFoundation/AVFoundation.h>框架 ,代码如下

#import "MusicTableViewCell.h"
#import "UIView+SDAutoLayout.h"
#import <AVFoundation/AVFoundation.h>
@interface MusicTableViewCell () <AVAudioPlayerDelegate>@property (nonatomic,strong) AVAudioPlayer *player;  //播放器
@property (nonatomic,strong) UIButton *button;
@property (nonatomic,strong) UIProgressView *progress; //播放进度条
@property (nonatomic,strong) UISlider *slider;   //用滑动器来控制音量大小
@property (nonatomic,strong) NSTimer *timer;   //更新歌曲当前时间
@property (nonatomic,strong) UILabel *timeLabel;  //显示时间
@end@implementation MusicTableViewCell - (void)awakeFromNib {[super awakeFromNib];// Initialization code
}-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];if(self){self.selectionStyle=UITableViewCellSelectionStyleNone;self.player.delegate=self;[self creatUI];}return self;
}-(void)creatUI{self.picView=[[UIImageView alloc]init];[self.contentView addSubview:self.picView];self.userNameLabel=[[UILabel alloc]init];self.userNameLabel.textAlignment=NSTextAlignmentLeft;self.userNameLabel.font=[UIFont systemFontOfSize:19];[self.contentView addSubview:self.userNameLabel];self.userPhtoView=[[UIImageView alloc]init];[self.contentView insertSubview:self.userPhtoView atIndex:0];self.button=[UIButton buttonWithType:UIButtonTypeCustom];  //改为UIButtonTypeCustom ,按键不会默认蓝色[self.button setImage:[UIImage imageNamed:@"开始-6"] forState:UIControlStateNormal];[self.button addTarget:self action:@selector(play:) forControlEvents:UIControlEventTouchUpInside];[self.contentView addSubview:self.button];self.progress=[[UIProgressView alloc]init];     //实例化进度条self.progress.progress=0;[self.contentView addSubview:self.progress];self.timeLabel=[[UILabel alloc]init];self.timeLabel.textColor=[UIColor lightGrayColor];[self.contentView addSubview:self.timeLabel];self.slider=[[UISlider alloc]init];self.slider.minimumValue=0;self.slider.maximumValue=10;[self.slider setThumbImage:[UIImage imageNamed: @"圆盘-2"] forState:UIControlStateNormal];self.slider.transform=CGAffineTransformMakeRotation(-M_PI_2);[self.slider addTarget:self action:@selector(changeVo) forControlEvents:UIControlEventTouchUpInside];[self.contentView addSubview:self.slider];self.titleLabel=[[UILabel alloc]init];self.titleLabel.font=[UIFont systemFontOfSize:23];[self.contentView addSubview:self.titleLabel];self.detailLabel=[[UILabel alloc]init];self.detailLabel.textColor=[UIColor lightGrayColor];[self.contentView addSubview:self.detailLabel];self.picView.sd_layout.leftSpaceToView(self.contentView, 10).topSpaceToView(self.contentView, 10).widthIs(40).heightIs(40);self.userNameLabel.sd_layout.leftSpaceToView(self.picView, 10).centerYEqualToView(self.picView).widthIs(150).heightIs(30);self.userPhtoView.sd_layout.leftEqualToView(self.picView).topSpaceToView(self.picView, 15).rightSpaceToView(self.contentView, 10).heightIs(160);self.button.sd_layout.centerYEqualToView(self.userPhtoView).centerXEqualToView(self.userPhtoView).widthIs(80).heightIs(80);self.progress.sd_layout.topSpaceToView(self.button, 20).leftSpaceToView(self.contentView, 20).rightSpaceToView(self.contentView, 50).heightIs(15);self.timeLabel.sd_layout.widthIs(200).leftEqualToView(self.progress).topSpaceToView(self.button, 3).heightIs(15);self.slider.sd_layout.bottomEqualToView(self.progress).widthIs(10).rightSpaceToView(self.contentView, 18).heightIs(100);self.titleLabel.sd_layout.leftEqualToView(self.userPhtoView).rightEqualToView(self.userPhtoView).topSpaceToView(self.userPhtoView, 15).autoHeightRatio(0);self.detailLabel.sd_layout.leftEqualToView(self.titleLabel).rightEqualToView(self.titleLabel).topSpaceToView(self.titleLabel, 15).autoHeightRatio(0);[self setupAutoHeightWithBottomView:self.detailLabel bottomMargin:20];}-(void)time{NSTimeInterval totalTime=self.player.duration;NSTimeInterval currentTime=self.player.currentTime;self.progress.progress=(currentTime/totalTime);NSTimeInterval currentM=currentTime/60;currentTime=(int)currentTime%60;NSTimeInterval totalM=totalTime/60;totalTime=(int)totalTime%60;NSString *timeString=[NSString stringWithFormat:@"%02.0f:%02.0f|%02.0f:%02.0f",currentM,currentTime,totalM,totalTime];self.timeLabel.text=timeString;}-(void)changeVo{self.player.volume=self.slider.value;
}-(void)play:(UIButton *)sender{self.isPlay=!self.isPlay;if(self.isPlay==NO){[self.button setImage:[UIImage imageNamed:@"开始-6"] forState:UIControlStateNormal];[self.player pause];self.userPhtoView.alpha=1;}else{[self.button setImage:[UIImage imageNamed:@"暂停-6"] forState:UIControlStateNormal];[self.player play];self.userPhtoView.alpha=0.6;  //本来是使背景图变模糊,结果没成功,现在是修改透明度}//    [self.delegate didClickPlay:self];   //协议方法,传递值是当前cell,即self
}-(void)setModel:(MusicModel *) musicModel{NSURL *musicUrl=[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:musicModel.musicName ofType:@"mp3"]];self.player=[[AVAudioPlayer alloc]initWithContentsOfURL:musicUrl error:nil];self.timer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(time) userInfo:nil repeats:YES];self.titleLabel.text=musicModel.titleName;self.detailLabel.text=musicModel.detailName;self.picView.image=[UIImage imageNamed:musicModel.PicName];self.userNameLabel.text=musicModel.userName;self.userPhtoView.image=[UIImage imageNamed:musicModel.userPhotoName];}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated];}

但是该部分代码还存在一些问题,比如 存在多个cell的播放器可以同时播放音乐的情况 ,还比如播放结束后,播放按键不会自动切换为“开始”图标,仍然是“暂停”图标。

接下来进行“早午茶”界面的布局 ,定义一个dinnerModel

.h文件定义如下

#import <Foundation/Foundation.h>@interface DinnerModel : NSObject
@property (nonatomic,strong) NSString *userName;
@property (nonatomic,strong) NSString *userIconName;
@property (nonatomic,strong) NSString *detail;
@property (nonatomic,strong) NSArray *PhotoNameArray;
@property BOOL shouldForMore;
@property BOOL isOpen;
@end

因为定义内容的显示最多不超过三行,所以声明了一个shouldForMore 布尔型变量,引入外部变量maxHeight (在DinnerTableViewCell中已经为外部变量maxHeight赋值为三行文本的高度),如果文本高度超过maxHeight,shouldForMore为YES,反之,则为NO 。.m文件定义如下

#import "DinnerModel.h"
#import <UIKit/UIKit.h>extern CGFloat maxHeight;
@implementation DinnerModel{CGFloat _lastContentWidth;
}
@synthesize detail=_detail;-(void)setDetail:(NSString *)detail{_detail=detail;
}-(NSString *)detail{CGFloat contentw=[UIScreen mainScreen].bounds.size.width-70;if(contentw !=_lastContentWidth){_lastContentWidth=contentw;CGRect textRect=[_detail boundingRectWithSize:CGSizeMake(contentw, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:18]} context:nil];if(textRect.size.height>maxHeight) {_shouldForMore=YES;   //超过三行,需要“查看更多”}else{_shouldForMore=NO;   //不需要“查看更多”}}return _detail;
}@end

接下来是DinnerTableViewCell的布局代码。DinnerTableViewCell.h代码如下

#import <UIKit/UIKit.h>
#import "DinnerModel.h"
#import "PhotoContainer.h"@class DinnerTableViewCell;@protocol forMoreProtocol <NSObject>
-(void)didClickForMore:(DinnerTableViewCell *)cell;
@end@interface DinnerTableViewCell : UITableViewCell
@property (nonatomic,strong) UIImageView *userImg;
@property (nonatomic,strong) UILabel *userLabel;
@property (nonatomic,strong) UILabel *detailLabel;
@property (nonatomic,strong) UILabel *formore;
@property BOOL isOpen;
@property (nonatomic,strong) PhotoContainer *phtoContainer;
@property (nonatomic,weak)id <forMoreProtocol>delegate;
-(void)setModel:(DinnerModel *)dinnerModel ;
@end

因为点击具体cell中的“查看更多”,会实现展开特定的cell中的内容。.h文件中声明了一个forMoreProtocol协议,通过该协议传递当前cell,TwoViewController中调用该协议,实现该协议定义的方法,TwoViewController中的相关代码如下

-(void)didClickForMore:(DinnerTableViewCell *)cell{NSIndexPath *indexPath=[self.dinnerTV indexPathForCell:cell];DinnerModel *model=_dinnerArray[indexPath.row];model.isOpen=!model.isOpen;
//    [self.dinnerTV  reloadData];[self.dinnerTV reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];    //更新当前行
}

DinnerTableViewCell.m代码如下

#import "DinnerTableViewCell.h"
#import "UIView+SDAutoLayout.h"CGFloat maxHeight=0;
@implementation DinnerTableViewCell- (void)awakeFromNib {[super awakeFromNib];// Initialization code
}-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];if(self){[self create];self.selectionStyle=UITableViewCellSelectionStyleNone;}return self;
}-(void)create{self.userImg =[[UIImageView alloc]init];[self.contentView addSubview:self.userImg];self.userLabel=[[UILabel alloc]init];self.userLabel.font=[UIFont systemFontOfSize:23];[self.contentView addSubview:self.userLabel];self.detailLabel=[[UILabel alloc]init];self.detailLabel.font=[UIFont systemFontOfSize:18];if(maxHeight==0){maxHeight=self.detailLabel.font.lineHeight*3;}   //一开始把这句话放在第一行,结果行数没到三行也显示了“查看更多”,因为没赋值成功正确的行高[self.contentView addSubview:self.detailLabel];self.formore=[[UILabel alloc]init];self.formore.text=@"查看更多";self.formore.textColor=[UIColor grayColor];self.formore.font=[UIFont systemFontOfSize:14];[self.contentView addSubview:self.formore];UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(More:)];self.formore.userInteractionEnabled=YES;[self.formore addGestureRecognizer:tap];self.phtoContainer=[[PhotoContainer alloc]init];[self.contentView addSubview:self.phtoContainer];self.userImg.sd_layout.leftSpaceToView(self.contentView, 20).topSpaceToView(self.contentView, 10).widthIs(50).heightIs(50);self.userLabel.sd_layout.leftSpaceToView(self.userImg, 15).topSpaceToView(self.contentView, 10).widthIs(150).heightIs(25);self.detailLabel.sd_layout.topSpaceToView(self.userLabel, 10).leftEqualToView(self.userLabel).rightSpaceToView(self.contentView, 5).autoHeightRatio(0); //还是要写上这句高度自适应self.formore.sd_layout.topSpaceToView(self.detailLabel, 5).leftEqualToView(self.userLabel).widthIs(100);self.phtoContainer.sd_layout.topSpaceToView(self.formore, 5).leftEqualToView(self.userLabel);
}-(void)More:(UITapGestureRecognizer *)recognizer{[self.delegate didClickForMore:self];
}-(void)setModel:(DinnerModel *)dinnerModel {self.userImg.image=[UIImage imageNamed:dinnerModel.userIconName];self.userLabel.text=dinnerModel.userName;self.detailLabel.text=dinnerModel.detail;self.phtoContainer.statePhotoArray=dinnerModel.PhotoNameArray;UIView *bottomV;if(dinnerModel.shouldForMore){self.formore.sd_layout.heightIs(25);self.formore.hidden=NO;if(dinnerModel.isOpen){self.detailLabel.sd_layout.maxHeightIs(MAXFLOAT);self.formore.text=@"收起";}else{self.detailLabel.sd_layout.maxHeightIs(maxHeight);self.formore.text=@"查看更多";}if(dinnerModel.PhotoNameArray.count){bottomV=self.phtoContainer;}else{bottomV=self.formore;}}else{self.formore.sd_layout.heightIs(0);self.detailLabel.sd_layout.autoHeightRatio(0);self.formore.hidden=YES;if(dinnerModel.PhotoNameArray.count==0){bottomV=self.detailLabel;}else{bottomV=self.phtoContainer;}}[self  setupAutoHeightWithBottomView:bottomV bottomMargin:20];  //因为忘记这句,所以布局又乱了
}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {[super setSelected:selected animated:animated];// Configure the view for the selected state
}@end

至此,“早午茶”界面的布局基本完成

在TwoViewController.m中根据当前tableView ,依次调用不同的cell进行赋值 ,相关代码如下

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{if(tableView==self.videoTV)return _videoArray.count;else if(tableView==self.musicTV)return  _musicArray.count;else if(tableView==self.dinnerTV)return _dinnerArray.count;else{return 1;}
}-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{static NSString *iden=@"iden";if(tableView==self.videoTV){VideoTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:iden];if(cell==nil){cell=[[VideoTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden];}cell.delegate=self;[cell setModel:_videoArray[indexPath.row]];return cell;}else if(tableView==self.musicTV){MusicTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:iden];if(cell==nil){cell=[[MusicTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden];}
//        cell.delegate=self;[cell setModel:_musicArray[indexPath.row]];return cell;}else if(tableView==self.dinnerTV){DinnerTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:iden];if(cell==nil){cell=[[DinnerTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden];}cell.delegate=self;[cell setModel:_dinnerArray[indexPath.row]];return cell;}else{UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:iden];if(cell==nil){cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden];}cell.textLabel.text=@"14";return cell;}
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{//cell高度自适应if(tableView==_videoTV){return [self.videoTV cellHeightForIndexPath:indexPath model:self.videoArray[indexPath.row] keyPath:@"model" cellClass:[VideoTableViewCell class] contentViewWidth:[self cellContentViewWith]];}else if(tableView==_musicTV){return [self.musicTV cellHeightForIndexPath:indexPath model:self.musicArray[indexPath.row] keyPath:@"model" cellClass:[MusicTableViewCell class] contentViewWidth:[self cellContentViewWith]];}else if(tableView==_dinnerTV){return [self.dinnerTV cellHeightForIndexPath:indexPath model:self.dinnerArray[indexPath.row] keyPath:@"model" cellClass:[DinnerTableViewCell class] contentViewWidth:[self cellContentViewWith]];}else{return 40;}
}- (CGFloat)cellContentViewWith{CGFloat width = [UIScreen mainScreen].bounds.size.width;// 适配ios7横屏if ([UIApplication sharedApplication].statusBarOrientation != UIInterfaceOrientationPortrait && [[UIDevice currentDevice].systemVersion floatValue] < 8) {width = [UIScreen mainScreen].bounds.size.height;}return width;
}

ios——扩充完善第二个demo (多练习delegate的用法)相关推荐

  1. KaiOS 超越 iOS 成为印度第二大移动操作系统

    2019独角兽企业重金招聘Python工程师标准>>> 据 DeviceAtlas 最新数据显示,在 2018 年第一季度,KaiOS 已超越 iOS 成为印度第二大移动操作系统. ...

  2. iOS开发-声网Agora Demo

    iOS开发-声网Agora Demo 前言 开发准备 代码 关于其他详细的文档 前言 声网Agora是最近类似七牛云和腾讯云的直播视频类的付费SDK,官网上的Demo不是很易懂,所以下面举个例子. 开 ...

  3. iOS 请求头第二次cookie中获取不到PHPSESSID的问题

    iOS 请求头第二次cookie中获取不到PHPSESSID的问题 最近在项目中让我遇到了一个很蛋疼的问题,我们的App中混合的有H5的界面,但是H5页面也需要对登录信息进行验证.于是我们就用了coo ...

  4. iOS 中KVC、KVO、NSNotification、delegate 总结及区别

    iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属 ...

  5. ios 团购信息客户端demo(一)

    团购信息客户端,主要整合了ASIHTTPREQUEST,KISSXML,AQGridView,MBProgressHUD这几个主要流行的IOS开发库,我们先来看一下效果图 首先我们新建一个IOS工程, ...

  6. 【iOS】——暑假第二周3Gshare总结

    3Gshare总结 在这周完成了3Gshare的demo,3Gshare的难度和代码量都和仿写网易云相比有了很大的提升,在这个过程中遇到了很多问题和bug,在解决问题的过程中也学到了很多. 1.启动页 ...

  7. iOS开发 常用的框架demo

    总结了一些常用的demo,包括获取验证码.AVPlayer.AFNetworking.Masonry.高仿微信.高仿网易.K线图.折线图.柱状图.手势解锁.TouchID.直播.动画等,大家可以根据需 ...

  8. 我的第一次份实习工作-iOS实习生-第二个月

    第二个月 来公司过了一个月了.每天早上9点上班,到晚上6.30下班,上下班要指纹打卡,第一个月忘了打卡好多次(),然后还要去补打卡单.公司这边还安排了,工资卡办理,招商银行卡.开了一次新员工大会,认识 ...

  9. iOS 仿滴滴出行界面~demo

         联系人:石虎 QQ:1224614774  昵称: 嗡嘛呢叭咪哄                           QQ群:807236138  群称: iOS 技术交流学习群       ...

最新文章

  1. 轻量级简单队列服务HTTPSQS安装与使用
  2. 设计模式之_动态代理_03
  3. 电脑卡顿,最先升级这个硬件,运行速度可快速提升!
  4. php 设置excel格式,php 操作excel文件的方法小结
  5. zabbix监控linux网卡流量,zabbix实现linux流量变化率监控
  6. JDBC 学习笔记(一)—— 基础知识 + 分页技术
  7. 系统封装 如何为原生PE集成软件
  8. echarts 广州地图入门案例
  9. 【组合数学】组合恒等式总结 ( 十一个组合恒等式 | 组合恒等式证明方法 | 求和方法 ) ★
  10. oracle的PRIPID字段,oracle常用库表和常用导数逻辑.doc
  11. Boosting算法与假设间隔
  12. JAVA我的世界给op_我的世界OP指令有哪些 OP权限怎么设置
  13. 【原理图】电路中的VCC VDD VSS VEE GND含义 以及STM32电源
  14. APS(高级计划与排程)基本概念
  15. 微信小程序流量主怎么开通,小程序流量主开通步骤
  16. 一个小试题:英雄角色PK
  17. “特殊值、类型和转换”学习笔记
  18. 操作系统总结--进程,线程
  19. HTML基础总结第一节
  20. 学习python(七)——zip() 、reserved()、sorted()

热门文章

  1. 用Python和Pygame写游戏-从入门到精通(11)
  2. 用Python暴力求解德·梅齐里亚克的砝码问题
  3. Spring自定义标签使用及原理
  4. Chrome浏览器不能同步书签的解决方法
  5. 关于小米路由器升级系统保留SSH的简单方法(RedmiAX5实验)
  6. Kindel资源去哪里找
  7. 改进的point in polygon problem算法介绍
  8. 微信小程序模拟拨打电话
  9. 「内部分享」阿里巴巴 开源软件列表、建议收藏!
  10. XGBoost, LightGBM