具有许多子视图的糟糕的UIScrollView性能

时间:2022-10-11 23:07:25

I am building a simple app which displays a users Contacts with photos like this -

我正在构建一个简单的应用程序,显示用户联系人与这样的照片 -

具有许多子视图的糟糕的UIScrollView性能

The contacts are each a positioned subview, with another subview inside containing a UIImageView to generate the images w/rounded corners and a UILabel.

触点每个都是一个定位的子视图,内部的另一个子视图包含一个UIImageView,用于生成带圆角的图像和UILabel。

Scrolling becomes rather choppy on both iPhone 4/4s and iPhone 5, however, even with only 6-7 contacts. Also, the choppyness seems to be constant. It doesn't matter if they have 8 contacts or 500 contacts, it doesn't get worse or better either way.

iPhone 4/4和iPhone 5上的滚动变得相当不稳定,但即使只有6-7个联系人。此外,波动性似乎是不变的。如果他们有8个联系人或500个联系人并不重要,它不会变得更糟或更好。

Does anybody know why this might be? The algorithm that generated this grid can be seen below. Are there any specific properties on the UIScrollView I haven't set, etc?

有人知道为什么会这样吗?生成此网格的算法如下所示。我没有设置的UIScrollView上是否有任何特定属性等?

- (void) generateContactGrid
{
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(self.addressBook);
    CFIndex nPeople = ABAddressBookGetPersonCount(self.addressBook);


    int peopleInARow = 0;
    int maxPeopleInARow = 3;
    int positionFromTop = 20;
    int IMAGE_SIZE = 70;
    float animationOffset = .5;
    float animationOffsetChange = .3;
    float animationDuration = .5;
    int scaleOffset = 40;
    int screenWidth = 320;
    int startingPositionFromLeft = 26;
    int positionFromLeft = startingPositionFromLeft;
    int topOffset = 40;
    int leftOffset = 26;
    int numberOfRows = 0;


    UIView *contactContainer;
    UIImage* image;
    CALayer *l;
    NSString *name;
    NSString *lastName;
    NSString *firstName;
    UIImageView *newimageview;
    UILabel *label;
    UIView *contactImageContainer;



    for ( int i = 0; i < nPeople; i++ )
    {
        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
        firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person,kABPersonFirstNameProperty);
        lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
        name = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

        if(ABPersonHasImageData(person)){
            NSLog(@"Current Contact Being Generated: %@", name);
            image = [UIImage imageWithData:(__bridge NSData *)ABPersonCopyImageData(person)];

            NSLog(@"Contact's Position From Left: %i", positionFromLeft);
            newimageview = [[UIImageView alloc] initWithFrame:CGRectMake(-scaleOffset/2, -scaleOffset/2, IMAGE_SIZE+scaleOffset, IMAGE_SIZE+scaleOffset)];
            newimageview.contentMode = UIViewContentModeScaleAspectFit;
            [newimageview setImage: image];
            contactContainer = [[UIView alloc] initWithFrame:CGRectMake(positionFromLeft, positionFromTop + 20, IMAGE_SIZE, 200)];
            contactImageContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, IMAGE_SIZE, IMAGE_SIZE)];
            contactImageContainer.clipsToBounds = YES;

            l = [contactImageContainer layer];
            [l setMasksToBounds:YES];
            [l setCornerRadius:IMAGE_SIZE/2];

            [l setBorderWidth:0.0];
            [l setBorderColor:[[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:.6] CGColor]];


            [contactImageContainer addSubview:newimageview];

            [contactContainer addSubview:contactImageContainer];

            label =  [[UILabel alloc] initWithFrame: CGRectMake(0, IMAGE_SIZE + 10, IMAGE_SIZE, 20)];
            label.text = firstName;
            label.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0];
            label.textColor = [UIColor whiteColor];
            [label setTextAlignment:NSTextAlignmentCenter];
            [label setFont:[UIFont fontWithName:@"Arial-BoldMT" size:14]];
            [contactContainer addSubview:label];


            contactContainer.alpha = 0;

            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:animationDuration];
            [UIView setAnimationDelay:animationOffset];
            animationOffset+= animationOffsetChange;
            [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

            contactContainer.alpha = 1;
            CGRect temp = contactContainer.frame;
            temp.origin.y = positionFromTop;
            contactContainer.frame = temp;

            [UIView commitAnimations];

            if(peopleInARow >= 2){
                positionFromTop += IMAGE_SIZE + topOffset;
                peopleInARow = 0;
                positionFromLeft = startingPositionFromLeft;
                numberOfRows++;

            } else {
                peopleInARow += 1;
                positionFromLeft += IMAGE_SIZE + leftOffset;
            }

            [self.scrollView addSubview:contactContainer];
            [self.scrollView bringSubviewToFront:contactContainer];


        }

    }

    NSLog(@"%i", numberOfRows);

    self.scrollView.contentSize = CGSizeMake(screenWidth, 150 * numberOfRows);

}

1 个解决方案

#1


1  

Use Instruments to measure what exactly makes your app slow. Everything else is just guessing.

使用Instruments来衡量究竟是什么让你的应用变慢。其他一切都只是在猜测。

But I will guess anyways. This most likely is the masking you apply to your UIImageViews. Try disabling that and see if it is still slow (and by see I mean measure, of course). If that is indeed the cause there are two things you can try. First you can set the shouldRasterize property of the masked layer and see if that actually is enough. This could make things worse though if your layers get changed a lot. The other option would be to render those masked pictures with Core Graphics instead of using layers.

但无论如何我会猜。这很可能是您应用于UIImageViews的屏蔽。尝试禁用它,看看它是否仍然很慢(当然,看看我的意思是措施)。如果这确实是原因,那么你可以尝试两件事。首先,您可以设置被遮罩图层的shouldRasterize属性,看看它是否足够。如果您的图层发生了很大变化,这可能会使事情变得更糟。另一种选择是使用Core Graphics渲染这些蒙版图片而不是使用图层。

#1


1  

Use Instruments to measure what exactly makes your app slow. Everything else is just guessing.

使用Instruments来衡量究竟是什么让你的应用变慢。其他一切都只是在猜测。

But I will guess anyways. This most likely is the masking you apply to your UIImageViews. Try disabling that and see if it is still slow (and by see I mean measure, of course). If that is indeed the cause there are two things you can try. First you can set the shouldRasterize property of the masked layer and see if that actually is enough. This could make things worse though if your layers get changed a lot. The other option would be to render those masked pictures with Core Graphics instead of using layers.

但无论如何我会猜。这很可能是您应用于UIImageViews的屏蔽。尝试禁用它,看看它是否仍然很慢(当然,看看我的意思是措施)。如果这确实是原因,那么你可以尝试两件事。首先,您可以设置被遮罩图层的shouldRasterize属性,看看它是否足够。如果您的图层发生了很大变化,这可能会使事情变得更糟。另一种选择是使用Core Graphics渲染这些蒙版图片而不是使用图层。