2010-05-12 8 views
11

Tôi đã thêm UITableView làm chế độ xem con cho lớp UIView tùy chỉnh mà tôi đang làm việc. Tuy nhiên tôi nhận thấy rằng bất cứ khi nào tôi di chuyển bảng nó gọi các lớp của tôi layoutSubviews. Tôi khá chắc chắn của nó UIScrollview rằng bảng được kế thừa từ đó là thực sự làm điều này nhưng muốn biết nếu có một cách để vô hiệu hóa chức năng này và nếu không phải là lý do tại sao nó xảy ra? Tôi không hiểu tại sao khi bạn cuộn một scrollview nó cần superview của nó để bố trí subviews của nó.UIScrollview gọi superviews layoutSubviews khi cuộn?

Code:

@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 

+0

Nhưng cho tôi biết tại sao bạn làm như vậy Tại sao các bạn thêm xem bảng để xem tùy chỉnh? – Manjunath

+0

Câu chuyện dài, tôi đang tạo một PickerView tùy chỉnh cho phép nhiều lựa chọn và có kích thước khác với tiêu chuẩn. Về cơ bản nó hiển thị một nền PickerView chuyển đổi với một bảng rõ ràng trên đầu trang – marchinram

+0

Bạn đã xem xét điều này? Anh chàng này dường như có vấn đề ngược lại, trong đó layoutSubviews ISN'T được gọi. Ông cũng đề cập đến một sửa chữa, mà nếu bạn đảo ngược nó, có thể làm việc ra cho bạn. :) http://stackoverflow.com/questions/728372/when-is-layoutsubviews-called – Kalle

Trả lời

2

Có, UIScrollView không gọi bố cục xem trước khi cuộn. Tôi có thể tuyên thệ điều này được nêu trong tài liệu ở đâu đó, nhưng tôi đoán là không.

Dù sao, ý tưởng phổ biến cho điều này là một UIScrollView nên bố trí công cụ của nó để quan điểm mà hiện tại không thể được nhìn thấy không nên được đặt ra. Khi người dùng cuộn trong chế độ xem cuộn, cần thêm và xóa các bản xem phụ nếu cần. Tôi đoán đây là những gì mà TableViews sử dụng để enqueue các ô bảng bị ẩn đi.

Có lý do nào khiến bạn quan tâm nếu bố cục xem được gọi hay không?

+0

không, tôi đã chạy một số mã trong đó mà tôi không nên có được chạy, mà làm cho tinh thần rằng nó đưa ra các bản xem xét khi có thay đổi vị trí trong scrollview – marchinram

+2

Bạn là đúng, nhưng vấn đề thực sự là việc cuộn chế độ xem cuộn cũng kích hoạt 'layoutSubviews' trong * superview * của nó, điều này có thể tốn kém và không cần thiết. Tôi nghi ngờ đó là một tác dụng phụ của việc thay đổi giới hạn của khung nhìn cuộn, nhưng nó cũng có thể chỉ là một lỗi. – Costique

0

Không chắc tôi hiểu vấn đề của bạn một cách chính xác nhưng khi bạn di chuyển một tableview nó loại bỏ các tế bào không được hiển thị từ bộ nhớ và tải chúng một lần nữa khi chúng được cuộn lại thành tầm nhìn (các tế bào được phân bổ theo yêu cầu, chỉ những cái có thể nhìn thấy được), thực hiện những gì bạn có vẻ đang mô tả.

1

UITableView ít nhất cũng xuất hiện để bố cục giám sát của nó. Hành vi này có thể có vấn đề khi bạn có phương thức layoutSubviews có thể tốn kém (ví dụ: nếu bạn gọi một số JavaScript).

Khắc phục nhanh chóng là thêm một chế độ xem phụ trung gian ngăn chế độ xem cuộn từ trình giám sát của bạn. Thay vào đó, nó sẽ bố trí subview trung gian.

Đây có thể là một chút không hoàn hảo nhưng nó phải làm việc cho hầu hết các trường hợp:

Giả UIView * intermediateView được định nghĩa như là một biến Ví dụ:

-(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 
}