我正在尝试将此代码转换为在后台线程上执行for循环,因为它非常慢并且非常滞后。
-(void)prepareLayout {
[super prepareLayout];
if (!_animator) {
_animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
CGSize contentSize = [self collectionViewContentSize];
NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
for (UICollectionViewLayoutAttributes *item in items) {
UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
spring.length = 0;
spring.damping = self.springDamping;
spring.frequency = self.springFrequency;
[_animator addBehavior:spring];
}
}
}
我确实试过这个但是它没有正常工作......它摆脱了滞后但是一些行丢失或者在集合视图中的奇怪位置我觉得for循环不能正常使用dispatch。 .. - (void)prepareLayout { [super prepareLayout];
if (!_animator) {
_animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
CGSize contentSize = [self collectionViewContentSize];
NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
for (UICollectionViewLayoutAttributes *item in items) {
UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
spring.length = 0;
spring.damping = self.springDamping;
spring.frequency = self.springFrequency;
[_animator addBehavior:spring];
}
dispatch_sync(dispatch_get_main_queue(), ^{
});
});
}
}
我已尝试过其他版本,但无法让它工作......如果有人可以帮我转换此代码以正确运行后台线程,那会很棒...谢谢
答案 0 :(得分:0)
prepareLayout
中没有任何部分可以安全地放在后台主题上。 UIKit元素只能在主线程上访问。
prepareLayout
不应经常被调用,否则可能导致滞后。如果经常调用它,您需要经常查看布局失效的原因。
如果您的集合视图非常大(例如数百个项目),那么您的问题可能是您将太多项目附加到行为。您应该在创建行为时将项目附加到行为,并在删除行为时将其删除。 UIKit Dynamics不是为管理数百或数千件物品而设计的。
确保从WWDC 2013中观看Advanced Techniques with UIKit Dynamics。我发现组合UICollectionView和UIKit Dynamics并不明显(从幻灯片中的第110页开始)。如果您没有覆盖layoutAttributesForElementsInRect:
,请务必注意该讨论。