UIScrollview вызывает супервизор layoutSubviews при прокрутке?

Я добавил UITableView в качестве подзаголовка в пользовательский класс UIView, над которым я работаю. Однако я заметил, что всякий раз, когда я просматриваю таблицу, он вызывает мои классы layoutSubviews. Я почти уверен, что это UIScrollview, что таблица наследует от того, что на самом деле делает это, но хотел знать, есть ли способ отключить эту функциональность, и если не почему это происходит? Я не понимаю, почему, когда вы прокручиваете scrollview, ему нужен свой супервизор для компоновки его подзонов.

код:

@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

Ответ 1

Да, UIScrollView вызывает вызовы layoutsubviews всякий раз, когда он прокручивается. Я мог бы поклясться, что это было указано в документации где-то, но, я думаю, нет.

В любом случае преобладающая идея для этого заключается в том, что UIScrollView должен компоновать свой материал, чтобы представления, которые в настоящее время не видны, не должны быть изложены. Когда пользователи прокручиваются в представлении прокрутки, он должен добавлять и удалять субвью в случае необходимости. Я предполагаю, что это то, что TableViews используют для размещения ячеек таблицы, которые скрываются.

Есть ли какая-либо причина, по которой вам было бы интересно, вызваны ли вызовы layoutsubviews?

Ответ 2

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
}

Ответ 3

Не уверен, что я правильно понимаю вашу проблему, но когда вы просматриваете табличное представление, он удаляет ячейки, которые не отображаются в памяти, и загружает их снова, когда они прокручиваются обратно в видимость (ячейки распределяются по требованию, только видимые), в эффект делает то, что вы, кажется, описываете.