删除 UICollectionView 边缘的单元格 - 滚动后单元格不会立即出现

2023-11-25

考虑一个标准的垂直滚动流布局,其中填充了足够的单元格以引起滚动。当滚动到底部时,如果删除一个项目,使得集合视图的内容大小必须缩小以容纳新的项目数(即删除底行的最后一个项目),则从滚动到底部的单元格行顶部被隐藏。在删除动画结束时,顶行出现时没有动画 - 这是一个非常不愉快的效果。

慢动作:

Cells not appearing

重现起来非常简单:

  1. 创建一个新的单视图项目并更改默认值ViewController是一个子类UICollectionViewController

  2. Add a UICollectionViewController到使用标准流程布局的故事板,并将其类更改为ViewController。为单元原型指定标识符“Cell”,大小为 200x200。

  3. 添加以下代码到ViewController.m:


@interface ViewController ()
@property(nonatomic, assign) NSInteger numberOfItems;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.numberOfItems = 19;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.numberOfItems;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    self.numberOfItems--;
    [collectionView deleteItemsAtIndexPaths:@[indexPath]];
}

@end



附加信息

在处理集合视图时,我见过这个问题的其他表现形式,只是上面的例子似乎最简单地演示了这个问题。UICollectionView在默认动画期间似乎进入某种恐慌的瘫痪状态,并且拒绝在动画完成之前取消隐藏某些单元格。它甚至可以防止手动调用cell.hidden = NO对隐藏单元产生影响(hidden还是YES然后)。下降到底层并设置hidden如果您可以获得对要取消隐藏的单元格的引用,那么这是可行的,这在处理尚未显示的单元格时并不简单。

-initialLayoutAttributesForAppearingItemAtIndexPath正在为调用时可见的每个项目调用deleteItemsAtIndexPaths:,但不适用于滚动到视图中的内容。可以通过调用来解决该问题reloadData随后立即在批量更新块内,这似乎使集合视图意识到顶行即将出现:

[collectionView deleteItemsAtIndexPaths:@[indexPath]];
[collectionView performBatchUpdates:^{
    [collectionView reloadData];
} completion:nil];

但不幸的是,这对我来说不是一个选择。我正在尝试通过操作单元格层和动画并调用来实现一些自定义动画计时reloadData导致不必要的布局回调,确实让事情变得不正常。



更新:一些调查

我向许多布局方法添加了日志语句,并查看了一些堆栈帧以尝试找出问题所在。至关重要的是,我正在检查何时layoutSubviews当集合视图向布局对象请求布局属性时调用(layoutAttributesForElementsInRect:) 什么时候applyLayoutAttributes:被细胞调用。

我希望看到这样的一系列方法:

// user taps cell (to delete it)
-deleteItemsAtIndexPaths:
-layoutAttributesForElementsInRect:
-finalLayoutAttributes...:                // Called for the item being deleted
-finalLayoutAttributes...:                // \__ Called for each index path visible
-initialLayoutAttributes...:              // /   when deletion started
-applyLayoutAttributes:                   // Called for the item being deleted, to apply final layout attributes
// collection view begins scrolling up
-layoutSubviews:                          // Called multiple times as the 
-layoutAttributesForElementsInRect:       // collection view scrolls
// ... for any new set of
// ... attributes returned:
-collectionView:cellForItemAtIndexPath:
-applyLayoutAttributes:                   // Sets the standard attributes for the new cell
// collection view finishes scrolling

其中大部分正在发生;当视图滚动时,布局会正确触发,并且集合视图会正确查询布局以获取要显示的单元格的属性。然而,collectionView:cellForItemAtIndexPath:以及相应的applyLayoutAttributes:直到删除之后才调用方法,当最后一次调用布局时,导致隐藏单元格被分配其布局属性(设置hidden = NO).

因此,尽管从布局对象收到了所有正确的响应,但集合视图似乎设置了某种标志,以在更新期间不更新单元格。有一个私有方法UICollectionView从内部呼唤layoutSubviews这似乎负责刷新细胞的外观:_updateVisibleCellsNow:。这是在应用单元格起始属性之前最终要求数据源提供新单元格的地方,这似乎是失败点,因为它在应该调用的时候没有被调用。


另外,这似乎与更新有关动画片,或者至少单元格没有更新duration的插入/删除。例如,以下工作没有故障:

- (void)addCell
{
    NSIndexPath *indexPathToInsert = [NSIndexPath indexPathForItem:self.numberOfItems
                                                         inSection:0];
    self.numberOfItems++;
    [self.collectionView insertItemsAtIndexPaths:@[indexPathToInsert]];
    [self.collectionView scrollToItemAtIndexPath:indexPathToInsert
                                atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                        animated:YES];
}

如果调用上述方法来插入单元格,而插入的单元格位于当前可见边界之外,则将在没有动画的情况下插入该项目,并且集合视图滚动到该项目,从而正确地出列并显示单元格。

iOS 7 和 iOS 8 beta 5 中出现问题。


调整内容插图,使其稍微超出设备屏幕尺寸的范围。

collectionView.contentInsets = UIEdgeInsetsMake(-5,0,0,0); //Adjust this value until it looks ok
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

删除 UICollectionView 边缘的单元格 - 滚动后单元格不会立即出现 的相关文章

  • UIBarButtonItem 按下后更改字体,在外观代理中指定

    我设置了UIBarButtonItem标题字体通过appearanceAppDelegate 中的代理 UIBarButtonItem appearance setTitleTextAttributes NSDictionary dicti
  • 在 swift ios 中播放远程 mp3 文件需要花费大量时间

    我有麻烦了 我想在我的应用程序中播放远程 mp3 文件 但 mp3 文件需要很长时间 大约 5 6 分钟 来播放 为什么 任何人都可以建议我应该做什么 import UIKit import AVFoundation class TestV
  • 适用于 iOS 的 MvvmCross 汉堡菜单

    我在用着https www marcbruins nl xamarin ios hamburger menu mvvmcross https www marcbruins nl xamarin ios hamburger menu mvvm
  • TestFlight Beta 中的消息不可用

    I am seeing Unavailable message in TestFLight Beta App in iOS8 Please find the attached screenshot please tell me how to
  • iOS 5 UIView drawRect 覆盖在设备上不起作用

    我正在准备在 iOS 5 GM 上发布我的 iPhone 应用程序 并遇到了 UIView 的错误 当我在子类上重写 drawRect 方法时 模拟器会显示所需的结果 但当我尝试在实际设备上测试时 drawRect 重写根本没有任何效果 我
  • iOS FacebookSDK + 解析 SDK + GoogleMaps SDK

    我搜索了很多 然后我意识到 ObjC标记那个GoogleMapSDK需要 但不能很好地配合ParseSDK and FacebookSDK 所以我阅读了所有的 stackoverflow 答案并尝试解决我的问题 问题还没有解决 我执行的步骤
  • iOS 何时清理本地应用程序 ./tmp 目录?

    iOS什么时候清理本地应用程序 tmp目录 请注意 这不是一个骗局这个问题 https stackoverflow com questions 3593900 iphone storage in tmp directory 我问的是应用程序
  • Swift:Tableview 在导航栏下方滚动但在状态栏上方滚动?

    我使用以下技巧隐藏了导航栏的阴影 self navigationController navigationBar setBackgroundImage UIImage for default self navigationControlle
  • 如何在导航栏上添加 UIView?

    我需要覆盖UINavigationBar with UIView像这儿 除了使用带有按钮返回的自定义 UIView 作为导航栏之外 还有其他方法可以做到这一点吗 您可以将子视图添加到应用程序的基本视图 UIApplication share
  • 在 Swift 中的 For 循环中更改对象的属性

    我创建了一个名为 ShoppingList 的简单结构 struct ShoppingList var shoppingListId NSNumber var title String var groceryItems GroceryIte
  • Bootstrap 响应式表格在 iOS 设备上无法垂直滚动

    这就是我所拥有的 div class table responsive table class table style background transparent table div 我正在使用以下 bootstrap css 文件 ht
  • Grand Central Dispatch (GCD) 调度源标志

    我最近不再使用 to GCD 调度来源 https developer apple com documentation dispatch 1385630 dispatch source create监视文件更改 效果很好 API 也变得更加
  • iOS 有 INTERNET 权限吗?

    我在 iOS 设备上的 flutter dio 包上遇到了一个奇怪的问题 我编写了一个向 url 发送 GET 请求的应用程序 Android 上一切正常 但 iOS 上的请求似乎无法通过 没有发生任何错误 什么也没有 我在 Android
  • UITableViewCell 内嵌套 UIStackView 内的 UILabel 有时会被截断

    我的一个表设置中有一个表视图单元格 其中包含以下视图层次结构 外部水平 stackview 固定到单元格内容视图的尾部 前部 底部和顶部边缘 右侧标签固定到其父 stackViewHackView 的尾部 前部 底部和顶部边缘 在我的控制器
  • 如何将设备上未保存的图片上传到dropbox帐户?(IOS)

    Dropbox RestClient 仅保存文件 所以我想先将图像保存在本地文件夹中 然后上传它 结果它保存了文件 但它已损坏 NSString localPath NSBundle mainBundle pathForResource I
  • Swift - 保存在 TableView 中选择的复选标记

    我对 Swift 相当陌生 并且在 TableView 多重选择方面遇到问题 我有多个选择 可以用复选标记进行检查 类似于待办事项列表 当我检查项目时 我希望能够返回 ListView 并保存我的选择 我假设将其保持在已保存状态的代码将位于
  • 如何从第二个视图弹回到根视图?

    我使用 2 将 3 个视图 根视图 第 1 个视图 第 2 个视图 连接在一起modal在 Apple Watch 故事板中继续 1 在根视图中 按下 保存 按钮后 将显示第一个模态视图 2 在第一模态视图中 一旦按下 500 按钮 将显示
  • iOS 搜索栏不显示结果

    更新 这实际上有效 我的自定义单元格的样式尚未出现 因此单元格看起来是空白的 那我怎样才能得到searchResultsTableView使用我的自定义单元格 我在表格视图中实现了搜索栏 当我调试时搜索 过滤所有工作 但是当我在搜索栏中输入
  • 获取所有ios应用程序的全局列表[重复]

    这个问题在这里已经有答案了 我想对苹果应用商店进行一些全球统计 一个瓶颈是至少获取所有当前活动应用程序的 ID 这 9 位数字 有谁知道如何获取 iOS 应用商店中当前活动应用程序的所有 id 的完整列表 更好的是特定类别的所有 ID 例如
  • 如何制作像 Facebook 应用程序一样的登录屏幕?

    如何制作像 Facebook 应用程序一样带有 电子邮件 和 密码 文本字段的登录屏幕 Facebook登入 http extdesenv com wp content uploads 2012 05 facebook login ios

随机推荐