- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我能够在一个非常简单的独立应用程序上重现它。
我有一个 collectionView,我想制作循环/循环,以便元素一次又一次地重复(也就是当用户位于数组中的最后一个元素时,它会再次显示第一个元素。如果它们位于第一个和向左滚动,它再次显示最后一个元素)。所以这是一个永无止境的 collectionView。
举个简单的例子,让我们使用星期几:
....周日、周一、周二、周三..周六、周日、周一....
为了实现这一点,我在 numberOfItemsInSection
中返回了一个大数字 (10000),并在 cellForItemAtIndexPath
中使用了 indexPath.item%7
> 调整和获取正确元素的方法。使用 %7
因为有 7 天。我的单元格非常简单——里面只有一个 UILabel。
这一切都很完美。
sizeForItemAtIndexPath
有问题。我希望细胞适合标签。由于只有 7 个实际大小变化,所以我将 7 天的大小预先缓存在字典中,并在 sizeForItemAtIndexPath
方法中返回正确的大小。
问题是(由于错误或 Apple 对 collectionview 的故意错误设计),sizeForItemAtIndexPath
在 collectionview 出现之前获取每个 indexPath 的调用。因此,如果我想要循环 collectionView 逻辑并需要返回大数字 (10000),它会为所有 10000 个索引调用 sizeForItemAtIndexPath
。所以在 collectionView 出现之前会有几秒钟的延迟。如果我注释掉 sizeForItemAtIndexPath
,它会立即生效。所以这绝对是问题所在。我在 sizeForItemAtIndexPath
中放置了一个 NSLog
,它会在加载前记录所有 22222 调用。
我什至定义了 setEstimatedItemSize
,它仍然为所有索引调用 sizeForItemAtIndexPath
。
我可以通过返回较小的数字 1000 来减少延迟,但这仍然是一个糟糕的设计或错误。
TableView 没有这个错误——你可以定义一百万行,它只在实际需要时调用 heightForRow。所以我不确定为什么 collectionView 需要在显示之前为所有单元格调用它,特别是如果 setEstimatedItemSize
也已经定义。
这个 bug 的另一个副作用是如果我返回一个更大的值,collectionView 会抛出一个错误(50000 让它中断,22222 没问题)。它打印值太大的错误:
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future.
TableView 可以轻松处理巨大的值,因为它没有这个错误。
我也试过禁用prefetching
,但没有效果。
大家怎么看?
相关代码:
#define kInfiniteCount 22222
#define kDayNameMargin 30
@interface ViewController (){
NSMutableDictionary *dictOfSizes;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
self.myCalendar = [NSCalendar currentCalendar];
[self.myCalendar setLocale:locale];
dictOfSizes = [NSMutableDictionary new];
for (int i=0; i<7; i++) {
WeekdayCollectionViewCell *sizingCell = [[NSBundle mainBundle] loadNibNamed:@"WeekdayCell" owner:self options:nil][0];
sizingCell.myLabel.text=[self.myCalendar weekdaySymbols][i];
[sizingCell layoutIfNeeded];
[dictOfSizes setObject:[NSValue valueWithCGSize:[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]] forKey:sizingCell.myLabel.text];
}
self.myCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.myCollectionView registerNib:[UINib nibWithNibName:@"WeekdayCell" bundle:nil] forCellWithReuseIdentifier:@"daycell"];
[(UICollectionViewFlowLayout*)self.myCollectionView.collectionViewLayout setEstimatedItemSize:CGSizeMake(200, self.myCollectionView.frame.size.height)];
[self.myCollectionView reloadData];
NSInteger middleGoTo = kInfiniteCount/2;
while (![[self.myCalendar weekdaySymbols][middleGoTo%7] isEqualToString:@"Monday"]) {
middleGoTo--;
}
[self.myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:middleGoTo inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return kInfiniteCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
WeekdayCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"daycell" forIndexPath:indexPath];
cell.myLabel.text=[self.myCalendar weekdaySymbols][indexPath.item%7];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"sizeForItemAtIndexPath: %ld",indexPath.item);
return [(NSValue*)[dictOfSizes objectForKey:[self.myCalendar weekdaySymbols][indexPath.item%7]] CGSizeValue];
}
编辑:
很少有人提到为此使用 scrollview 而不是 collectionview。
几乎在我研究圆形 ScrollView 的所有地方,他们都建议为此目的使用 Collection View ,因为它更容易。我的实际要求有点复杂,这需要我也使用 collectionview。
Scrollview 需要你使用 scrollViewDidScroll 方法并且每次都改变内容偏移量。此外,它会立即将所有 View 加载到内存中,因为它没有像 collectionview 那样重用现有单元格的优势。所以这是另一个内存点。
7 个工作日是我使用的一个简单示例。如果有人想显示大量数据(100),那在 ScrollView 和 Collection View 中将是一个非常糟糕的实现,将出现此错误。
最佳答案
这是预期的行为,与 UICollectionView
没有太大关系- 更多UICollectionViewFlowLayout
你使用的。
由于每个单元格的大小不同,FlowLayout 将分别请求每个单元格的大小,以计算总大小 CollectionView
- 这是正确处理滚动、滚动条所必需的。
UITableView 它更简单一些,因为它的布局更简单(只有高度很重要)- 这就是为什么可以在那里使用 estimatedSize 的原因。
整体Core Layout Process
在这里有很好的解释:
为了克服这个问题,我建议使用您的自定义 UICollectionViewLayout
并移动您的缓存逻辑并重新使用 CollectionViewLayout
内单元格的大小, 不在你的 ViewController
.
关于ios - 在加载之前为所有索引调用 sizeForItemAtIndexPath - 我很确定我遇到了 UICollectionView 错误或糟糕的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53453681/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!