【问题标题】:iOS - UIScrollView doesn't update its content and some UIViews disappear after reloadiOS - UIScrollView 不更新其内容,并且某些 UIView 在重新加载后消失
【发布时间】:2012-11-26 20:56:34
【问题描述】:

我在 UIView 内有 UITableViewControllerUIScrollView 作为其标题。 UIScrollView 用于显示图片的幻灯片:

UITableView
 -UITableViewHeaderView
   -UIView
      -UIScrollView
        -UIImageView
          ...
      -UIPageControl

每张图片都有一个带有标题和描述的子视图:

UIImageView
  -UIView
    -UILabel
    -UILabel

当我需要更新我的tableView 时,会调用一个委托方法,该方法会重新加载tableView 中的数据并调用addImages 方法:

- (void)eventsUpdated
{
    if ([self respondsToSelector:@selector(setRefreshControl:)])
        [self.refreshControl endRefreshing];

    [self.tableView reloadData];
    [self addImages];
}

这是我添加图片的方法:

- (void)addImages
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    for (int i = 0; i < images.count; i++) {
        CGRect frame;
        frame.origin.x = self.scrollView.frame.size.width * i;
        frame.origin.y = 0;
        frame.size = self.scrollView.frame.size;

        UIImageView *subview = [self createImageViewForEvent:[images objectAtIndex:i] inFrame:frame];
        subview.frame = frame;
        [self.scrollView addSubview:subview];
    }

    self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width*images.count, scrollView.frame.size.height);
    pageControll.currentPage = 0;
    pageControll.numberOfPages = images.count;

}

- (UIImageView *)createImageViewForEvent:(Event *)event inFrame:(CGRect)frame
{
    UIImage *image;

    NSString *imageName = [event.imageName lastPathComponent];
    NSString *bundleFilePath = [[NSBundle mainBundle] pathForResource:[imageName stringByDeletingPathExtension] ofType:[imageName pathExtension]];

    image = [UIImage imageWithContentsOfFile:bundleFilePath];


    UIImageView *output = [[UIImageView alloc] initWithImage:image];
    output.frame = frame;

    UIView *descriptionView = [[UIView alloc] initWithFrame:CGRectMake(0, frame.size.height*0.7, frame.size.width, frame.size.height*0.3)];

    descriptionView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    descriptionView.alpha = 1.0;

    UILabel *header = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, frame.size.width-20, 12)];
    header.textColor = [UIColor colorWithRed:210/256.0 green:217/256.0 blue:231/256.0 alpha:1.0];
    header.font = [UIFont fontWithName:@"Helvetica" size:17];
    header.backgroundColor = [UIColor clearColor];
    header.lineBreakMode = UILineBreakModeTailTruncation;
    header.numberOfLines = 1;

    UILabel *description = [[UILabel alloc] initWithFrame:CGRectMake(10, 22, frame.size.width-20, 28)];
    description.textColor = [UIColor colorWithRed:255/256.0 green:255/256.0 blue:255/256.0 alpha:1.0];
    description.font = [UIFont fontWithName:@"Helvetica" size:12];
    description.backgroundColor = [UIColor clearColor];
    description.lineBreakMode = UILineBreakModeTailTruncation;
    description.numberOfLines = 2;

    header.text = event.title;
    [descriptionView addSubview:header];

    description.text = event.shortDesription;
    [descriptionView addSubview:description];

    [output addSubview:descriptionView];

    return output;
}

首次启动后一切正常,但如果我尝试重新加载我的tableView 并再次调用addImages,所有UILabel 都会消失,只有UIImageViewUIView 可见。

UPD:

我注意到,我的 UILabel 会在一段时间后出现,大约在 30 秒后。我以前从未经历过类似的事情

UPD 2:

重新加载我的tableViewscrollview 后,scrollView's 的内容不会立即更新,只有在我开始滚动后才会更新

【问题讨论】:

  • 您的frame 尺寸第二次出现错误了吗?
  • 如果frame.size 在任一维度上都为 0,那么标签就会消失,而 frame.size 将是什么并不完全清楚。我会用 NSLog 来检查。但我只是猜测,因为我没有看到其他明显的东西!
  • 不,它不为零。其中一个子视图仍然可见(输出),但不显示其所有子视图
  • 是的,我做到了。我的 scrollView 属性是(强,非原子)
  • @Oleg 你在主线程上调用addImages吗?

标签: iphone objective-c ios cocoa-touch uiview


【解决方案1】:

我从您发布的代码中复制了一个示例项目,在标签或任何其他组件上都没有发现任何令人耳目一新的问题。这使我认为问题不在于您发布的代码,而在于其他地方。

通常当你看到这样的延迟时,那是因为一些不应该并行运行的代码正在并行运行。

我建议您检查一下您拨打eventsUpdated 的方式和时间。您必须确保在主线程上执行调用,并且仅在事件数组完成更新后执行。要检查这一点,您可以在eventsUpdated 中添加以下行:

NSLog(@"Current: %@, main: %@", [NSThread currentThread], [NSThread mainThread]);

请发布日志! :-)

我建议您还将调用eventsUpdated 的方法中的代码添加到您的问题中,因为它也可能会有所帮助。

【讨论】:

  • 你完全正确!在我强制在 mainThread 上执行 addImages 之后,不知何故在后台线程上调用了我的委托方法,一切都到了它的位置:-) 谢谢你让我再次仔细检查一切!你得到我来之不易的 50 分 :-)
  • 好答案,我花了最后几个小时试图找出我的标签出现和消失的原因,甚至从未想过这可能是我添加的线程优化。即使我将视图添加到主线程上的滚动视图中,我在后台线程上添加到视图中的标签也不会立即出现
【解决方案2】:

一开始,千万不要这样做

 [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

滚动视图有一些内部视图(例如滚动指示器),因此您要删除它们,这可能会释放它们并在以后随时导致奇怪的崩溃。

至于您的问题 - 尝试调用 UIImageView 的 bringSubviewToFront: 以将您的标签放在其他所有内容的前面

【讨论】:

    猜你喜欢
    • 2022-07-12
    • 2014-01-02
    • 2021-11-09
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2016-12-17
    • 1970-01-01
    相关资源
    最近更新 更多