Ios 创建方法以动态确定哪个UICollectionViewCell位于屏幕中心

Ios 创建方法以动态确定哪个UICollectionViewCell位于屏幕中心,ios,objective-c,uiscrollview,uicollectionview,uicollectionviewcell,Ios,Objective C,Uiscrollview,Uicollectionview,Uicollectionviewcell,我目前正在开发一个Objective-CIOS应用程序,该应用程序的特点是场景具有全屏集合视图,单元格的大小几乎相当于整个屏幕的大小,垂直向下滚动场景 我希望能够以编程方式更改此集合视图中位于可见屏幕中心的单元格,我当前实现此功能的方式是等待集合视图上的滚动停止,然后编辑位于屏幕中心的任何单元格,如下面的方法所示: - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ NSIndexPath *centerCe

我目前正在开发一个Objective-CIOS应用程序,该应用程序的特点是场景具有全屏集合视图,单元格的大小几乎相当于整个屏幕的大小,垂直向下滚动场景

我希望能够以编程方式更改此集合视图中位于可见屏幕中心的单元格,我当前实现此功能的方式是等待集合视图上的滚动停止,然后编辑位于屏幕中心的任何单元格,如下面的方法所示:

- (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

}
虽然这种实现此功能的方法在一定程度上有效,但对单元格的更改仅在用户停止滚动时开始


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

编辑单元格==糟糕。更改模型==很好

因此,向数据源添加一个NSInteger,如
indexOverCenter
。将其初始化为无效的值,如-1。然后,在委托中检测条件:

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

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

    self.indexOverCenter = centerCellIndexPath.row;
    // don't edit the cell here:  yuck
    // reload it:  nice
    [self.collectionViewFollwersFeed reloadItemsAtIndexPaths:@[ centerCellIndexPath ]];
}

在cellForItemAtIndex中进行“编辑”工作,将传递的indePath行与indexOverCenter进行比较。如果它们相等,那么在那里进行特殊的格式化。

我非常同意我受过教育的同龄人的观点

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

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

实例化时将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;
}
确保单元格微弱地保留
观察到的滚动视图
,以避免保留循环

然后在单元格的.m文件中注册一个KVO观察者:

// MyCollectionViewCell.m

- (void)startObservingPosition {
   if (self.observedScrollView) {
      [self.observedScrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:NULL];
   }
}
请确保在单元解除分配之前删除KVO观察器。。。否则就崩溃!你也可以考虑使用一个好的内置的自动发布< /P> 每次KVO观察者触发时(当scrollView滚动时),您都可以确定位置并做出相应的反应

此示例显示了如何检测单元格何时位于中心,但也说明了如何执行更多操作:

// 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...
         }  
      }
    }
} 
//MyCollectionViewCell.m
-(void)observeValueForKeyPath:(NSString*)对象的键路径:(id)对象更改:(NSDictionary*)更改上下文:(void*)上下文{
if([keyPath IsequalString:@“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){
//contentView位于可查看提要的中心。请执行动画。。。
}  
}
}
} 

在我的收藏视图中,我将其导出如下:

private func findCenterIndex() -> Int {
        let center = self.view.convert(numberCollectionView.center, to: self.numberCollectionView)
        let row = numberCollectionView!.indexPathForItem(at: center)?.row


        guard let index = row else {

            return 0
        }


        self.rating = index

        return index

    }

因此,您可以轻松地将其转换为objective-c代码

scrollViewDidScroll如何?