在后台线程中向ScrollView添加大量按钮 - 按钮不可见

时间:2014-10-29 11:13:16

标签: ios multithreading uiscrollview uibutton background-process

用户应该能够从大量不同的图标中选择一个图标。我创建了一个选择器对话框,允许用户进行选择。用于此选择器的ViewController仅包含一个UIScrollView。在每个图标的viewDidLoad中,按钮被添加到ScrollView。要选择图标,用户只需单击相应的按钮...

这很好用,但ViewController / picker需要几秒钟才能显示。这是因为viewDidLoad内的许多alloc / add操作。因此,我尝试将这些选项移动到后台线程中。这样可以正常工作,但创建的按钮不再可见:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.iconsScrollView.hidden = true;
    [self.activityIndicator startAnimating];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        iconContainer = [[UIView alloc] init];
        iconContainer.backgroundColor = [UIColor clearColor];

        iconButtons = [[NSMutableDictionary alloc] init];

        CGRect buttonRect = CGRectMake(5, 5, 40, 40);
        selectedButton = nil;

        NSArray *iconInfos = [[StoreController sharedController] allIcons];

        for (IconInfo* iconInfo in iconInfos) {
            NSString *iconName = iconInfo.name;

            UIButton *iconButton = [UIButton buttonWithType:UIButtonTypeCustom];
            iconButton.frame = buttonRect;

            [iconButton addTarget:self action:@selector(iconSelectionClick:) forControlEvents: UIControlEventTouchUpInside];
            [iconButton setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal];

            [iconContainer addSubview:iconButton];
            [iconButtons setObject:iconButton forKey:iconInfo.guid];

            buttonRect.origin.x += 50;
            if (buttonRect.origin.x > 205) {
                buttonRect.origin.x = 5;
                buttonRect.origin.y += 50;
            }
        }

        iconContainer.frame = CGRectMake(0, 0, self.iconsScrollView.frame.size.width, ceil([iconButtons count] / 5.0) * 50);

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.iconsScrollView addSubview:iconContainer];
            self.iconsScrollView.contentSize = iconContainer.frame.size;

            [self.activityIndicator stopAnimating];
            self.iconsScrollView.hidden = false;

            [self.view setNeedsDisplay];
        });
    });
}

这几乎没有任何问题:

  • Picker ViewController出现
  • 在创建按钮时可以看到ActivityIndi​​cator
  • 一旦所有按钮都准备就绪,ActivityIndi​​cator就会停止,ScrollView也会变得可见。

仅问题:按钮不可见。 ScrollView可以正常使用(内容大小正确),当我触摸ScrollView内部并点击一个不可见按钮时,会调用单击选择器。因此所有按钮都在那里但不可见。最终在10-15秒后,所有按钮立刻变得可见。

对View,ScrollView或按钮使用setNeedsDisplaysetNeedsLayout不会改变任何内容。

知道我能做什么吗?

2 个答案:

答案 0 :(得分:1)

当您不在主线程上时,您正在向子视图添加按钮。

通常,UIKit代码只能在主队列上运行。

答案 1 :(得分:0)

UIKit只能从主线程

更新
dispatch_async(dispatch_get_main_queue(), ^(void){
    //Run UI Updates
});