【问题标题】:UICollectionView Scroll Performance HorribleUICollectionView 滚动性能糟糕
【发布时间】:2016-03-22 03:09:04
【问题描述】:

我的 collectionView 中有大约 14 个项目,滚动一点也不流畅。我正在使用自动布局(我的约束不记录错误),并且我正在使用cornerRadius 属性(它是一个消息传递应用程序)。

我尝试使用 Time Profiler 工具对其进行分析,这是我在滚动时看到的:

不幸的是,“Reveal in Xcode”是灰色的,所以我永远看不到哪一行正在占用。我正在计算每个项目的大小。我想知道巨大的 9377 毫秒延迟可能是什么?如果我没记错的话,我没有使用有序集合。

这是我的cellForItemAtIndexpath 方法:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    //Define Message
    Message *message = (Message *)[self.messages objectAtIndex:indexPath.item];

    //Check Message Type
    switch (message.type) {
        case MessageTypeText: {

            //Initialize Cell
            TextMessageItem *cell = (TextMessageItem *)[collectionView dequeueReusableCellWithReuseIdentifier:kTextMessageItemIdentifier forIndexPath:indexPath];

            //Return Cell
            return cell;

            break;
        }
    }

    return nil;
}

这是我计算高度的方法:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    //Retrieve the right message
    Message *message = (Message *)[self.messages objectAtIndex:indexPath.row];

    //Check Message Type
    switch (message.type) {
        case MessageTypeText: {

            //Create a temporary cell to get the correct size
            TextMessageItem *tempCell = [[TextMessageItem alloc] init];

            //Configure the cell
            [self collectionView:collectionView configureTextCell:tempCell atIndexPath:indexPath];

            CGSize s = [tempCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize withHorizontalFittingPriority:UILayoutPriorityDefaultHigh verticalFittingPriority:UILayoutPriorityDefaultLow];

            //Return Content Size
            return CGSizeMake(self.collectionView.bounds.size.width, s.height);

            break;
        }
    }

    //Return
    return CGSizeMake(0, 0);
}

我的WillDisplayCell方法:

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {

    //Retrieve message from our array of messages
    Message *message = (Message *)[self.messages objectAtIndex:indexPath.row];

    //Check Message Type
    switch (message.type) {
        case MessageTypeText: {

            //Cast Cell
            TextMessageItem *textItem = (TextMessageItem *)cell;
            [self collectionView:collectionView configureTextCell:textItem atIndexPath:indexPath];

            break;
        }
    }
}

最后,这是我自定义的configureTextCell 方法:

- (void)collectionView:(UICollectionView *)collectionView configureTextCell:(TextMessageItem *)item atIndexPath:(NSIndexPath *)indexPath {

    //Retrieve Message
    Message *message = (Message *)[self.messages objectAtIndex:indexPath.item];

    //Display Timestamp if Needed
    [self displayTimestampForItemIfNeeded:item atIndex:indexPath.item];

    //Update Top Message Padding Based On Who Sent The Previous Message
    [self updateDistanceFromPreviousMessageForItem:item atIndex:indexPath.item];

    //Display Delivery Status if Needed (e.g. Delivered)
    [self displayDeliveryStatusForItemIfNeeded:item atIndex:indexPath.item];

    //Set Message
    [item setMessage:message];
}

【问题讨论】:

  • 会不会是我的cellForItemAtIndexpath 没有正确实现?我的 UICollectionViewCell 子类以编程方式完成(没有故事板或 xib 文件),我注意到在初始加载时,它的 initWithFrame 方法正在为我的 self.messages 数组中的每个项目调用。这正常吗?

标签: ios objective-c xcode uicollectionview smooth-scrolling


【解决方案1】:

使用圆角半径或图层蒙版是降低滚动性能的好方法,因为合成成本更高。相反,您可以使用带有圆角的 CAShapeLayer 来支持您的视图或作为视图的子图层。或者,您可以将带有圆角的内容绘制到添加到视图中的图像中。您还应该避免让您的视图剪辑到边界。 (我是在远离电脑的手机上输入的,所以我现在无法粘贴任何 sn-ps。)

【讨论】:

  • 谢谢野马。让我尝试根据您的建议进行一些更改,看看是否有任何明显的不同。
  • 我尝试了你的建议,虽然它确实有点帮助,但它仍然明显滞后。时间分析器操作从 9377 毫秒下降到 8800 毫秒。所以真正的问题是……什么可能需要 8800 毫秒?这仅在我滚动时显示,而不是在 viewDidLoad 上显示,如果这有助于缩小范围。
  • 等我有时间,我会更仔细地查看您的代码。您永远不想做的另一件事是在 prepareForReuse 时间或 dequeueReusableCellWithReuseIdentifier 时间更改约束。在初始化时设置这些。
  • 在准备重用时,我如何知道我是否正在这样做?我目前在 willDisplayCell 这样做可以吗?
猜你喜欢
  • 1970-01-01
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 2013-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多