不得不说,自己抓数据写Model真的是件痛苦的事,怪不得官方要给API,不然都自己抓数据真的要累死.

看看今晚做到的效果(已经能够请求数据展示出来了)

最耗时间的操作应该就是根据json来写Model了

写了这么大一堆.

思路:

由于一共有图片、段子、视频、音频4种大分类,但每个分类都有固定的东西,例如用户头像、发帖时间这些都是固定有的,还有下面的点赞点踩。所以可以画个基类的xib

 

如图,然后分别画其他类型的XIB

这些XIB画好后,在使用的时候根据判断返回的type字段来比较,例如返回字段是图片类型,那么图片类型的控件就显示出来,视频和音频的控件就hidden掉.

if ([talkModel.type isEqualToString:@"image"] || [talkModel.type isEqualToString:@"gif"]) {
        //如果类型为图片,将自己视频和音频控件隐藏,图片控件显示
        self.myVideoView.hidden = YES;
        self.myVoiceView.hidden = YES;
        self.pictureView.hidden = NO;
        self.pictureView.talkModel = talkModel;
        self.pictureView.frame = talkModel.pictureF;
    }else if ([talkModel.type isEqualToString:@"video"]) {
        //如果类型是视频,将图片和声音控件隐藏,视频控件显示
        self.pictureView.hidden = YES;
        self.myVoiceView.hidden = YES;
        self.myVideoView.hidden = NO;
        self.myVideoView.talkModel = talkModel;
        self.myVideoView.frame = talkModel.videoF;
    }else if ([talkModel.type isEqualToString:@"audio"]) {
        //如果类型是音频,将图片和视频控件隐藏,音频控件显示
        self.pictureView.hidden = YES;
        self.myVideoView.hidden = YES;
        self.myVoiceView.hidden = NO;
        self.myVoiceView.talkModel = talkModel;
        self.myVoiceView.frame = talkModel.soundF;
    }else {
        //段子类型,将所有控件都隐藏(音频、视频、图片)
        self.pictureView.hidden = YES;
        self.myVoiceView.hidden = YES;
        self.myVideoView.hidden = YES;
    }

注意点

在计算cell高度的时候,需要获取返回的height和width字段,一定要将对应的类型写对,我在写的时候将段子类型的高度写成了图片类型,导致了图片类型的高度和宽度都为0

CGFloat picH = picW * self.image.height / self.image.width;

我计算高度用了除法,这就导致了除数为0,大家都知道0是不能为除数的,但是这里Xcode也没报警告也没报错误,最后是崩了,崩的原因为

*** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableViewRowData.

找了好久,通过NSLog打印才发现,居然打印出了nan这种东西,我返回的明明是CGFloat,然后Google了一下,有人说可能是没有给值初始化造成的,然后细细的看,才发现了这个小问题,以后一定要注意这点了,写除法的时候一定要保证除数不能为零啊!

 

睡觉!


上午

今天起来先把昨晚的问题解决,就是发现在段子正文下和点赞那些的距离不对,有一段空白,原因是因为

//计算文字的高度
        CGFloat textH = [self.text boundingRectWithSize:CGSizeMake(Main_Screen_Width - 2 * margin, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]} context:nil].size.height;

我计算文字高度的时候,给的字体属性是14,但是我在XIB里给label设置的字体大小不是14,导致了2者没对应上,高度就不一样了,就出现了上面的那一段空白,修改之后就好了

 还有个小问题,就是在没有数据的时候第一次刷新,因为整体是Tableview,就会有分栏的横线在那,看着很不舒服.

使用

//取消Tableview的分栏横线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

来取消分栏线

 

图片加载效果

注意点:

[self.imageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        //注意要写个1.0,刚开始没写1.0,/出来是整数,我说怎么进度条直接0到1了
        CGFloat progress = 1.0 * receivedSize / expectedSize;
        NSLog(@"%lf",progress);
        self.bgImage.hidden = NO;
        self.ProgressView.hidden = NO;
        self.ProgressView.progressLabel.textColor = [UIColor whiteColor];
        self.ProgressView.roundedCorners = 3;
        self.ProgressView.progressLabel.text = [NSString stringWithFormat:@"%.0f%%",progress*100];
        [self.ProgressView setProgress:progress animated:YES];

使用DACircularProgressView加载进度条的时候,要注意AFNetworking中Progress参数receivedSize/expectedSize要在前面加个1.0*,不然除下来是整数,其实这完全算是小细节,自己没注意.

 

还需要注意一点,在画XIB的时候,imageView控件的背景色要给个浅灰色,不然进度条就得给个其他颜色,不然进度条给白色,背景也是白色,进度条是看不见的,刚开始我就犯了这个错误,都是通过reveal发现进度条在啊,怎么看不见,才知道自己犯了个这么白痴的错误!

 

一定要取消自动布局效果,不然ImageView显示在cell的位置是乱的,还有要开启与用户交互,不然点击图片没效果

- (void)awakeFromNib {
    //取消UIView的自动调整布局
    self.autoresizingMask = UIViewAutoresizingNone;
    //给图片添加单击事件
    self.imageView.userInteractionEnabled = YES;//设置为能与用户交互
    [self.imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showImage)]];
}

 

实现视频播放(我用的是KRVideoPlayer,基于MPMoviePlayerController的),使用方法也很简单,如下

/**
 *  播放按钮
 */
- (IBAction)playBtnAction:(UIButton *)sender {
    [self playVideoWithURL:[NSURL URLWithString:_talkModel.video.video.lastObject]];
    //将krv的view加到self上,self本身为view,注意要.view
    [self addSubview:self.videoController.view];
}

/**
 *  播放视频
 */
- (void)playVideoWithURL:(NSURL *)url {
    if (!self.videoController) {
        self.videoController = [[KRVideoPlayerController alloc] initWithFrame:self.videoImage.bounds];
        __weak typeof(self)weakSelf = self;
        [self.videoController setDimissCompleteBlock:^{
            weakSelf.videoController = nil;
        }];
    }
    self.videoController.contentURL = url;
}

/**
 *  停止播放
 */
- (void)reset {
    [self.videoController dismiss];
    self.videoController = nil;
}

 注意点:

 使用KRVdieoPlay的时候,有一点要注意,全屏播放的时候必须在KRVideoPlayerController.m文件中添加一段,使其保证能够覆盖全屏

- (void)fullScreenButtonClick
{
    if (self.isFullscreenMode) {
        return;
    }
    self.originFrame = self.view.frame;
    CGFloat height = [[UIScreen mainScreen] bounds].size.width;
    CGFloat width = [[UIScreen mainScreen] bounds].size.height;
    CGRect frame = CGRectMake((height - width) / 2, (width - height) / 2, width, height);;
    //为了能让视频全屏覆盖在最上面播放
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    if (!keyWindow) {
        keyWindow = [[[UIApplication sharedApplication] windows] firstObject];
    }
    self.originView = self.view.superview;
    [keyWindow addSubview:self.view];
    
    [UIView animateWithDuration:0.3f animations:^{
        self.frame = frame;
        [self.view setTransform:CGAffineTransformMakeRotation(M_PI_2)];
    } completion:^(BOOL finished) {
        self.isFullscreenMode = YES;
        self.videoControl.fullScreenButton.hidden = YES;
        self.videoControl.shrinkScreenButton.hidden = NO;
    }];
}

 滑出屏幕停止播放

//解决重用
- (void)prepareForReuse {
    
    [super prepareForReuse];
    //滑出屏幕停止视频播放
    [self.myVideoView reset];
}