在后台线程中向 UIScrollView 添加大量按钮 - 按钮不可见
Posted
技术标签:
【中文标题】在后台线程中向 UIScrollView 添加大量按钮 - 按钮不可见【英文标题】:Adding larg number of Buttons to UIScrollView in background thread - Buttons not visible 【发布时间】:2014-10-29 11:13:15 【问题描述】:用户应该能够从大量不同的图标中选择一个图标。我创建了一个选择器对话框,允许用户进行选择。用于此选取器的 ViewController 仅包含一个 UIScrollView。在viewDidLoad
中,为每个图标添加一个按钮到 ScrollView。要选择一个图标,用户只需点击相应的按钮...
这工作正常,但 ViewController/picker 需要几秒钟才能显示。这是因为viewDidLoad
中有许多分配/添加操作。因此,我试图将这些选项移动到后台线程中。这工作正常,但创建的按钮不再可见:
- (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 出现 ActivityIndicator 在创建按钮时可见 一旦所有按钮都准备就绪,ActivityIndicator 就会停止并且 ScrollView 变得可见。唯一的问题:按钮不可见。 ScrollView 可以正常使用(内容大小正确),当我在 ScrollView 内部触摸并点击一个不可见的按钮时,会调用单击选择器。因此所有按钮都在那里但不可见。最终在 10-15 秒后,所有按钮都立即可见。
对 View、ScrollView 或按钮使用 setNeedsDisplay
或 setNeedsLayout
不会改变任何内容。
知道我能做什么吗?
【问题讨论】:
您只能从主线程有效地更改 UI。 【参考方案1】:当您不在主线程上时,您正在向子视图添加按钮。
一般来说,UIKit 代码应该只在主队列上运行。
【讨论】:
我已经尝试只在后台线程中创建按钮并将添加到 scrollView 的内容移回主线程。结果都是一样的。据我所知,现有 UI 的所有 UI“交互”(添加、删除、调整大小、属性更改)都必须在主线程中完成。但是与(还)不是视图树一部分的 UI 对象进行交互应该没有问题,不是吗? 好的,不冻结 UI 的正确解决方案是什么? 不要向滚动视图添加按钮,使用更有效的方式同时呈现多个项目 - 类似于集合视图。【参考方案2】:UIKit 只能从主线程更新
dispatch_async(dispatch_get_main_queue(), ^(void)
//Run UI Updates
);
【讨论】:
以上是关于在后台线程中向 UIScrollView 添加大量按钮 - 按钮不可见的主要内容,如果未能解决你的问题,请参考以下文章