【问题标题】:UIScrollview calling superviews layoutSubviews when scrolling?UIScrollview在滚动时调用superviews layoutSubviews?
【发布时间】:2011-02-18 10:37:12
【问题描述】:

我将 UITableView 作为子视图添加到我正在处理的自定义 UIView 类中。但是我注意到,每当我滚动表格时,它都会调用我的类 layoutSubviews。我很确定它的表继承的 UIScrollview 实际上正在执行此操作,但想知道是否有办法禁用此功能,如果没有,为什么会发生这种情况?我不明白为什么当你滚动一个滚动视图时它需要它的超级视图来布局它的子视图。

代码:

@implementation CustomView
- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.clipsToBounds = YES;

        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 15.0, 436.0, 132.0) style:UITableViewStylePlain];
        tableView.dataSource = self;
        tableView.delegate = self;
        tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        tableView.backgroundColor = [UIColor clearColor];
        tableView.showsVerticalScrollIndicator = NO;
        tableView.contentInset = UIEdgeInsetsMake(kRowHeight, 0.0, kRowHeight, 0.0);
        tableView.tag = componentIndex;

        [self addSubview:tableView];
        [tableView release];
    }
    return self;
}
- (void)layoutSubviews {
    // This is called everytime I scroll the tableview
}

@end

【问题讨论】:

  • 但是告诉我你为什么这样做?你为什么要在自定义视图中添加表格视图?
  • 长话短说,我正在创建一个自定义 PickerView,它允许多项选择,并且大小与标准不同。它基本上显示了一个 PickerView 背景,上面有一个清晰的表格
  • 你看过这个吗?这家伙似乎有相反的问题,因为没有调用 layoutSubviews。他还提到了一个修复,如果你把它倒过来,可能对你有用。 :) stackoverflow.com/questions/728372/…
  • 这种行为在 iOS 5 及更高版本中发生了变化 -- stackoverflow.com/questions/8036457/…

标签: iphone uitableview uiview uiscrollview


【解决方案1】:

UITableView 至少看起来会布置它的超级视图。当您有一个可能很昂贵的 layoutSubviews 方法时(例如,如果您调用一些 JavaScript),此行为可能会出现问题。

快速解决方法是添加一个中间子视图,以防止滚动视图布置您的超级视图。相反,它将布局中间子视图。

这可能有点不完美,但它应该适用于大多数情况:

假设UIView * intermediateView被定义为一个实例变量:

-(id) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame: frame];
    if (self)
    {
        UIScrollView * theScrollView; // = your scroll view or table view
        intermediateView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
        // Ensures your intermediate view will resize its subviews.
        intermediateView.autoresizesSubviews = YES;

        // Ensure when the intermediate view is resized that the scroll view
        // is given identical height and width.
        theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                                         UIViewAutoresizingFlexibleHeight;
        [intermediateView addSubview: theScrollView];

        // Ensure the frame of the scroll view is exactly the bounds of your
        // intermediate view.
        theScrollView.frame = bottomContainerView.bounds;
        [self addSubview: intermediateView];
    }
    return self;
}

-(void) layoutSubviews
{
    intermediateView.frame = CGRectMake(0, 50, 42, 42); // replace with your logic
}

【讨论】:

    【解决方案2】:

    是的,UIScrollView 会在滚动时调用 layoutsubviews。我可以发誓这在某处的文档中有所说明,但我猜不是。

    无论如何,流行的想法是 UIScrollView 应该布局其内容,以便不布局当前无法看到的视图。当用户在滚动视图中滚动时,它应该根据需要添加和删除子视图。我猜这就是 TableViews 用来将隐藏的表格单元排入队列的原因。

    你有什么理由关心 layoutsubviews 是否被调用?

    【讨论】:

    • 不,我在那里运行了一些我不应该运行的代码,这是有道理的,当滚动视图中的位置发生变化时它会布置子视图
    • 你是对的,但真正的问题是滚动滚动视图也会在其 superview 中触发layoutSubviews,这可能既昂贵又不必要。我怀疑这是更改滚动视图边界的副作用,但它也可能只是一个错误。
    【解决方案3】:

    不确定我是否正确理解了您的问题,但是当您滚动表格视图时,它会从内存中删除未显示的单元格,并在它们滚动回可见性时再次加载它们(单元格是按需分配的,只有可见的单元格),在效果就像你描述的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      相关资源
      最近更新 更多