作为一个视频播放软件,显示明星的基本信息是一个十分常见的需求。such as 腾讯视频、爱奇艺的明星页。
一个明星页面,不仅包括明星的头像、个人基本的info,也包括了他的代表影视作品、相关资讯、音乐作品、粉丝、相关明星等板块;还包括给它投票的区域、查看明星的排名等这些功能。
具体而言,对于一个明星页有以下需求:
1、展示明星头像、个人info
2、默认隐藏导航栏,在页面向下滑动的时候,逐渐显示导航栏,并完全显示出来。完全显示导航栏时,导航栏显示明星名字。
3、显示关注人数,并具有点击关注的功能
4、显示明星拥有的票数,以及排名,并提供用户进行投票的功能;查看排行榜单
5、排行榜单显示排名前20的明星,并能通过点击榜单中的cell,跳转到对应的明星主页;能够查看往期榜单
6、显示粉丝,最多显示投票最多的四个(如果有四个及以上)
7、显示明星的代表作品、相关资讯、音乐作品、明星铃声等模块。每个模块只显示4个作品,超过四个的,通过其他页面显示;点击这些模块中的作品能够进行对应的视频播放。
一、明星主页
明星主页是一个页面展示,我们可以使用一个VC去实现它。我们给这个VC取个名字:StarDetailViewController 表示明星主页。
明星主页最核心的一个控件是一个UICollectionView。我们在StarDetailViewController中定义这样的一个property,叫collectionView,用于实现影视作品、相关资讯、音乐作品、粉丝、相关明星等板块的展示。
在collectionView的上面,是一个UIView的子类。我们叫做StarInfoHeadView。用来显示明星头像、职业、生日、以及明星的背景大图片等。并实现关注人数以及提供给用户进行关注的button。在这里我们使用UILabel, UIImageView, UIButton等控件进行展示和实现相关的功能。具体要显示的内容,是通过server或者代理server返回的。所以需要使用model对server的数据进行保存,我们把这个model取名为StarInfoHeadModel。具体的设计在第三部分进行说明。
另外,我们要实现显示明星拥有的票数,以及排名,并提供用户进行投票的功能和查看排行榜单等。需要在collectionView中的cell中进行实现。我们设计一个UICollectionViewCell的子类,叫做StarVoteAreaCell。用于提供用户投票,显示明星排名,查看排名榜单,显示粉丝头像和所投的票数。
1)显示粉丝
粉丝数据使用StarFansModel进行保存。由于只显示4个fans,那么通过一个for循环,最多只创建4个fans的view。创建fans的方法,我们定义为:
- (void)fansViewCreate:(CGFloat)fans fansModel:(StarFansModel *)fansModel
其中,第一个参数用于控制fans在StarVoteAreaCell上的位置,而第二个参数则是将所需要的具体数据的model传进来。
利用这个创建fans View的方法,我们创建所有fans的实现如下:
NSInteger fansNum = model.fans.count; //model的fans属性是一个array结构,记录从server拿到的fans数据
if (fansNum > 4) { //最多显示4个fans
fansNum = 4;
}
if (fansNum > 0) {
for (int i = 0; i < fansNum; i++) {
[ self fansViewCreate:*self.width/4 fansModel:[model.fans objectAtIndex:i]];
}
}
2)关注明星
我们把关注明星以及取消关注明星的UI做到StarInfoHeadView这个视图中。当然这个可以自行斟酌,这个并不是重点。
很显然,关注的实现是需要走接口的。也就是说需要跟server进行交互。server端保存了该明星的关注人数,前端做的是提供给用户关注的功能。并将关注或者取消关注的行为跟server同步。在这里,我们假设已经将和server交互的接口封装完成。我们通过监听用户的关注行为,适时让server改变关注的人数。
在StarInfoHeadView中,我们分别下面属性,用来提供用户关注以及取消关注的功能,并显示此是关注的人数:
@property(nonatomic, strong) UIButton *concernBtn; //通过button进行点击关注或取消关注
@property(nonatomic, strong) UIImageView *concernView; //点击关注或者取消关注button显示
@property(nonatomic, strong) UILabel *concernLabel; //提示
@property(nonatomic, strong) UILabel *fansNumberLabel; //显示关注该明星的人数
@property(nonatomic, assign) BOOL isAlreadyConcern; //标记是否关注过该明星,已经关注过了则不能再进行关注
这里涉及到一个问题,就是何时显示关注该明星的人数。因为实际关注人数是保存在server中的数据库中的,当我们查看一个明星主页的时候,这个关注人数也是通过server下发的。如果我们点击concernBtn后,通过接口将关注行为上传到server,server端更新之后,再由server下发这种处理方式会有一定的延迟,用户体验相对较差。因此,这里我们采取另一种解决办法。当用户点击关注按钮后,客户端对关注人数进行+1的操作,并立即在fansNumberLabel中显示出来。同时上传相应的接口通知server端进行关注人数的更新。当再次刷新界面时,再通过server的关注人数对本地的数据进行更新。
三、滑动过程中变化导航栏的显隐
四、model的设计以及前后端数据交互