ios - 创建动态判断哪个UICollectionViewCell在屏幕中央的方法

标签 ios objective-c uiscrollview uicollectionview uicollectionviewcell

我目前正在开发一个 Objective-C iOS 应用程序,该应用程序具有带全屏 Collection View 的场景,其单元格几乎与整个屏幕一样大,可垂直向下滚动场景。

我希望能够以编程方式更改此 Collection View 中位于可见屏幕中心的单元格,而我目前实现此功能的方式是等待滚动停止在 Collection View 上,并且然后编辑位于屏幕正中心的任何单元格,如下面的方法所示:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSIndexPath *centerCellIndexPath =
    [self.collectionViewFollwersFeed indexPathForItemAtPoint:
     [self.view convertPoint:[self.view center] toView:self.collectionViewFollwersFeed]];

    UICollectionViewCell *cell;
    NSString *CellIdentifier;

    CellIdentifier = @"FollowersFeed";
    cell = [_collectionViewFollwersFeed cellForItemAtIndexPath:centerCellIndexPath];

    //edit cell here

}

虽然这种实现此功能的方法在一定程度上起作用,但只有当用户停止滚动时,单元格的变化才会开始。

我希望能够在新单元格覆盖中心位置的那一刻开始对中心单元格进行更改,而不必停止滚动。我该如何编辑此方法,以便当且仅当新单元格覆盖屏幕的中心位置时,才应调用此方法?

最佳答案

我非常同意我受过教育的同行 dahn .

话虽如此,您可能想要根据滚动位置实际设置动画,而不仅仅是在它到达中心时“更改”单元格...

为此,您可以让单元跟踪自己的位置:

在实例化时将 ScrollView 传递给单元格:

// MyCollectionView's DataSource

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"yourIdentifier" forIndexPath:indexPath];
    cell.observedScrollView = theScrollViewYouWantToTrack;
    [cell startObservingPosition];
    return cell;
}

确保单元格弱持有 observedScrollView,以避免保留循环

然后在你cell的.m文件中注册一个KVO观察者:

// MyCollectionViewCell.m

- (void)startObservingPosition {
   if (self.observedScrollView) {
      [self.observedScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:NULL];
   }
}

确保在单元释放之前移除 KVO 观察器……否则会崩溃!你也可以考虑使用一个不错的 enhanced KVO observer我构建了自动释放自身

每次 KVO Observer 触发(当 scrollView 滚动时)——你可以找出位置并做出相应的 react 。

此示例展示了如何检测单元格何时位于中心,还说明了如何可以做更多的事情:

// MyCollectionViewCell.m

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentOffset"]) {
      if (self.observedScrollView) {  
         CGPoint offset = self.observedScrollView.contentOffset;
         CGRect contentViewRect = [self.contentView convertRect:self.contentView.bounds toView:self.observedScrollView];
         CGFloat contentViewCenterY = contentViewRect.origin.y + contentView.size.height * 0.5 - offset.y;
         if (contentViewCenterY == self.observedScrollView.bounds.height * 0.5) {
            // the contentView is in the center of the viewable feed. do your animations...
         }  
      }
    }
} 

关于ios - 创建动态判断哪个UICollectionViewCell在屏幕中央的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41496901/

相关文章:

iphone - 将 Unichar 数组转换为单个 NSString

objective-c - iOS NSKeyedUnarchiver 调用单例 getter

ios - 如何在 ScrollView 中将图像置于最前面

iphone - 如何实现循环UIScrollView?

ios - 允许 UIScrollView 及其 subview 都响应触摸

ios - UIButton 半透明边框

objective-c - 在 getter 方法中设置属性是不是很糟糕?

objective-c - iOS如何实现一个协议(protocol)的@property

ios - 在编辑模式下将自定义单元格在 UITableView 中向右移动

javascript - 打开react-native-contacts后React Native iOS应用程序立即关闭