如何按顺序向 UIScrollView 添加子视图
我在按顺序将子视图添加到滚动视图时遇到问题。
我收到了从服务器返回的 JSON 响应,我将其解析为业务对象数组,然后将其发送到函数 updateCarousel,如下所示:
-(void) updateCarousel: (NSArray *)response{
if(response && response.count>0){
int i=0;
self.scrollView.hidden=NO;
[self.scrollView setNeedsDisplay];
self.pageControl.hidden=NO;
[self.scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
for (Business *business in response){
if (i >= MAX_INITAL_SEARCH_RESULTS)
break;
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
CardView *cardView = [[CardView alloc] initWithBusinessData:business andFrame:frame];
//I've tried the following code with and without wrapping it in a GCD queue
dispatch_queue_t addingQueue = dispatch_queue_create("adding subview queue", NULL);
dispatch_async(addingQueue, ^{
[self.scrollView addSubview:cardView];
});
dispatch_release(addingQueue);
cardView.backgroundColor = [UIColor colorWithWhite:1 alpha:0];
i++;
self.scrollView.contentSize = CGSizeMake(i*(self.scrollView.frame.size.width), self.scrollView.frame.size.height);
self.pageControl.numberOfPages=i;
}
}else{
self.scrollView.hidden=YES;
self.pageControl.hidden=YES;
NSLog(@"call to api returned a result set of size 0");
}
结果 - 尽管我尝试了很多方法 - 始终是相同:scrollView 一次性添加所有子视图,而不是通过循环处理它们。我不明白这怎么可能。如果我在循环末尾添加 sleep() ,它会以某种方式等待整个循环结束,然后再显示添加的子视图。它怎么知道结果数组有多长?我无能为力,请帮忙。
I'm having problems adding subviews to a scrollview sequentially.
I've got a JSON response coming back from the server which I parse into an array of Business objects, and I send off to the function updateCarousel, which looks like this:
-(void) updateCarousel: (NSArray *)response{
if(response && response.count>0){
int i=0;
self.scrollView.hidden=NO;
[self.scrollView setNeedsDisplay];
self.pageControl.hidden=NO;
[self.scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
for (Business *business in response){
if (i >= MAX_INITAL_SEARCH_RESULTS)
break;
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = scrollView.frame.size;
CardView *cardView = [[CardView alloc] initWithBusinessData:business andFrame:frame];
//I've tried the following code with and without wrapping it in a GCD queue
dispatch_queue_t addingQueue = dispatch_queue_create("adding subview queue", NULL);
dispatch_async(addingQueue, ^{
[self.scrollView addSubview:cardView];
});
dispatch_release(addingQueue);
cardView.backgroundColor = [UIColor colorWithWhite:1 alpha:0];
i++;
self.scrollView.contentSize = CGSizeMake(i*(self.scrollView.frame.size.width), self.scrollView.frame.size.height);
self.pageControl.numberOfPages=i;
}
}else{
self.scrollView.hidden=YES;
self.pageControl.hidden=YES;
NSLog(@"call to api returned a result set of size 0");
}
The result - despite the many things I've tried - is always the same: the scrollView adds the subviews all at once, not as they are processed through the loop. I don't understand how this is possible. If I add a sleep() at the end of the loop, it somehow waits for the whole loop to be over before it shows the subviews as added. How does it even know how long the results array is? I'm at my wits' end, please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设您没有使用任何额外的线程来处理数据。
您遇到的情况是应用程序卡住了执行您的方法。即使您一一添加子视图(它们之间有睡眠),也不会执行其他代码来处理您的添加。
1。您可以使用另一个线程来加载数据并添加子视图,但这需要同步到主线程(更复杂)。
2 您可以在多次调用中中断您的方法。在加载方法的两次调用之间,允许执行其他代码段,这意味着滚动视图将能够一一处理/显示您的子视图。
您需要将加载方法更改为如下所示:
这只是该问题的一种基本解决方案。例如,您需要考虑如果在加载完上一个响应数据之前更新响应数据会发生什么情况。
I assume you are not using any extra threads to process the data.
What you experience is the application is stuck executing your method. Even though you add your subviews one by one (with a sleep between them), no other piece of code is executed to handle your adding.
1. You can use another thread to load the data and add subviews but this needs to be synchronized to the main thread (more complicated).
2 You can break your method in multiple calls. Between 2 calls of your load method, other pieces of code are allowed to execute and this means the scrollview will be able to process/display your subviews one by one.
You will need to change your loading method to something like this:
This is just one basic solution to the problem. For example, you need to take into consideration what happens if you update
response
data before you finish loading the previous one.