最近在学习了iOS的UI控件,所以写了一个新闻列表,以巩固之前学习的常识。

预览图

iOS仿写仿写头条新闻页面

主页完成

主页主要用两个CollectionView联动完成新闻页面切换的作用。当点击新闻标题栏,新闻列表会跳转到相应的界面,翻滚新闻列表时,上方的标题栏也会随之翻滚。

//完成新闻页面翻滚作用
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    //点击标题栏的标题,完成新闻页面翻滚
  if (self.titleCollectionView == collectionView) {
    [collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
    NSIndexPath *viewIndexPath = [NSIndexPath indexPathForItem:indexPath.item inSection:0];
    [self.collectView scrollToItemAtIndexPath:viewIndexPath atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
    [self.collectView reloadData];
  }
}
//完成当新闻列表翻滚时,新闻标题栏也会随之翻滚
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  if ([scrollView isEqual:self.collectView]) {
        //计算偏移量
    CGFloat x = scrollView.contentOffset.x;
    CGFloat i = x / UIScreen.mainScreen.bounds.size.width;
    [self.titleCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
  }
}

数据烘托

运用NSURLSession网络恳求获取网络数据,由于无法获取到头条的新闻数据,所以运用了抓包东西Charles修改网络接口回来的数据(回来本地自定义的JSON数据),运用第三方库YYModle讲获取到的数据进行模块化,然后烘托到设计好的UI界面。代码中供给了两种将数据模块化的办法,运用第三方库YYModle能够让代码看起来愈加简洁。由于网络获取到的是图片的URL,所以运用第三方库SDWebImage将URL转换为图片,烘托到界面上。

- (void)requestdata:(RequestTitleData)block {
  NSString *urlString = @"https://www.baidu.com/content-search.xml";
  urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
  NSURL *url = [NSURL URLWithString:urlString];
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //GET恳求
  [request setHTTPMethod:@"GET"];
  NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
  NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
  NSURLSessionDataTask *datatask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error == nil) {
      NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
      //办法一:运用YYModel处理数据,将数据模块化
      YYModelList *model = [YYModelList yy_modelWithDictionary:dict];
//      办法二:将数据模块化
//      NSMutableArray *listArr = @[].mutableCopy;
//      for (NSDictionary *info in dic) {
//        ListData *list = [[ListData alloc] init];
//        [list configWithCollectionViewCell:info];
//        NSLog(@"");
//        [listArr addObject:list];
//      }
 
      dispatch_async(dispatch_get_main_queue(), ^{
        if (block) {
          block(model.data);
        }
      });
    }
  }];
  [datatask resume];
}

删去功用

点击删去按钮会弹出一个删去视图,点击删去视图上的“不感兴趣”按钮,即可成功删去选中的新闻列表,要删去一个新闻列表需求首要删去该列表的数据源然后再刷新视图。

//删去delegate完成
- (void)tableViewCell:(UITableViewCell *)tableViewCell clickDeleteButton:(UIButton *)button {
  DeleteTableViewCell *deleteView = [[DeleteTableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 844)];
  __weak typeof(self) wself = self;
  [deleteView showDeleteView:^{
    __strong typeof(wself) strongSelf = wself;
      NSIndexPath *delIndexPath = [wself.tableView indexPathForCell:tableViewCell];
      if(strongSelf.array.count > delIndexPath.row) {
        //删去数据源
        NSMutableArray *data = [wself.array mutableCopy];
        [data removeObjectAtIndex:delIndexPath.row];
        strongSelf.array = [data copy];
       //刷新
        [strongSelf.tableView reloadData];
      }
  }];
}

视频播映

视频播映功用用到了AVFoundation结构获取视频资源特点。视频播映器运用UICollectionView进行布局,为每一个item添加一个点击事件,当点击item时,视频开始播映。运用KVO监听播映状况。 由于播映器的生命周期是和cell绑定的,当咱们点击多个cell时,会有多个播映器同时播映,为解决这个问题,运用单例来对播映器进行管理,视频只会在咱们最新点击的item上播映。

- (void)playVideoWithUrl:(NSString *)videoUrl attachView:(UIView *)attachView {
  [self stopPlay];
  NSURL *videoURL = [NSURL URLWithString:videoUrl];
  //视频资源特点
  AVAsset *asset = [AVAsset assetWithURL:videoURL];
  self.playerItem = [AVPlayerItem playerItemWithAsset:asset];
  [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
  [self.playerItem addObserver:self forKeyPath:@"process" options:NSKeyValueObservingOptionNew context:nil];
  //获取视频时长
  CMTime duration = self.playerItem.duration;
  CGFloat videoDuration = CMTimeGetSeconds(duration);
  self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
  [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:(CMTime time) {
      NSLog(@"播映进展: %@",@(CMTimeGetSeconds(time)));
  }];
  self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  self.playerLayer.frame = attachView.bounds;
  [attachView.layer addSublayer:self.playerLayer];
  [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(handlePlay) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

Demo地址