2013-05-28 31 views
7

Mọi người đều biết rằng bạn không thể tin tưởng kích thước khung hình trên phương thức init/viewDidLoad của UIViewController; này:UIViewController viewDidLoad chiều rộng/chiều cao không chính xác

- (void)viewDidLoad: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

sẽ in kích thước sai trong nhiều dịp (đặc biệt là nó được khá nhiều chia ở chế độ nằm ngang)

Điều này sẽ thực sự trả về kết quả lúc nào cũng khắc phục vì vậy nó tốt để bố trí các subviews:

- (void)viewWillAppear: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

Vấn đề là viewWillAppears được gọi mỗi khi chế độ xem xuất hiện, do đó, nó không phù hợp để phân bổ hoặc thêm các bản xem phụ. Vì vậy, bạn kết thúc tuyên bố mỗi lần xem trong giao diện và bạn kết thúc với các tệp tiêu đề lớn mà tôi không thích chút nào vì hầu hết các mục không cần thao tác nhiều hơn sau khi thiết lập ban đầu.

Vì vậy, câu hỏi đặt ra là: Có cách nào tốt hơn để xử lý vị trí xem phụ không?

Câu hỏi hai là rất có liên quan, giả sử tôi có một lớp con của UIView bao gồm các phần phụ khác. Tôi khai báo nó bên trong giao diện của tôi, và tôi phân bổ/init nó trong phương thức init/viewDidLoad của tôi.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    ... 
    menu = [[SNKSlidingMenu alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    ... 
} 

Như chúng ta đã biết bây giờ chúng ta cần phải định vị lại nó trong viewWillAppear để có được một kết quả chính xác hơn

- (void)viewWillAppear:(BOOL)animated{ 
    .... 
    menu.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    .... 
} 

Vấn đề là tất nhiên tất cả các subviews cần phải được thay đổi vị trí là tốt. Điều này được thực hiện bởi hàm layoutSubviews được gọi tự động, nhưng chúng tôi gặp vấn đề tương tự: Tất cả các bản xem trước cần phải được khai báo bên trong giao diện của lớp SNKSlidingMenu .. Có cách nào xung quanh vấn đề này không?

Cảm ơn.

+1

sử dụng tự động trả lời hoặc đặt tự động hóa mặt nạ? – jrturton

Trả lời

7

Nếu bạn đang nhắm mục tiêu iOS 5.0 hoặc cao hơn, bạn có thể sử dụng viewWillLayoutSubviewsviewDidLayoutSubviews để thực hiện thay đổi.

Đối với câu hỏi thứ hai của bạn, nếu bạn cần truy cập vào biến mẫu trong phương thức khác ngoài init, bạn cần giữ nó xung quanh, tôi không thấy vấn đề gì với nó.

Tuy nhiên, bạn có thể thử sử dụng Bố cục tự động và thiết lập quy tắc giữa các bản xem phụ để nó tự động được đặt ra cho bạn mà không cần phải tham khảo.

+0

đồng ý, nhưng sau đó nó khá ngu ngốc khi phải sử dụng initWithFrame để khởi tạo mỗi lần xem. Có vẻ như rất nhiều mã trùng lặp với tôi và dường như buộc bạn phải sử dụng nhiều biến mẫu. Bố cục tự động chỉ dành cho iOS mới hơn. – ksn

+0

'autoresizingMask' cũ có thể là đủ cho bạn. Đối với mã trùng lặp: nếu bạn đang sao chép rất nhiều mã đó, bạn có thể tạo các lớp con 'UIView' tùy chỉnh để bạn không bị trùng lặp hoặc có các phương thức trợ giúp tạo các khung nhìn cho bạn. Nếu bạn đăng thêm mã, chúng tôi có thể giúp bạn nhiều hơn. – pgb

6

viewDidLoad chỉ được gọi khi xem bạn là tạo, nhưng rất nhiều điều có thể ảnh hưởng đến kích thước của frame, và nó không được gọi một lần nữa khi frame thay đổi.

Thay vào đó:

  • tạo subviews trong viewDidLoad
  • thiết lập kích thước của chúng trong viewWillLayoutSubviews.

Xem một số cuộc thảo luận thêm ở đây để xử lý luân chuyển: https://stackoverflow.com/a/16421170/1445366

2

viewWillLayoutSubviewsviewDidLayoutSubviews có thể giải quyết vấn đề này.
Nhưng hai lần bị meth sẽ được thực hiện nhiều lần hơn. đây là mã của tôi để có được chính xác self.view.frame.

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    ... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    // init you view and set it`s frame. this can get correct frame. 
    ... 
    } 
    ... 
} 
+0

Đây là giải pháp duy nhất có hiệu quả đối với tôi. Mặc dù, nó kinda xấu xí như một số quan điểm ban đầu lạ bật lên một tíc tắc trước khi đá dispatch_async trong Đối Swift4:. \t \t DispatchQueue.main.async { \t \t} –

Các vấn đề liên quan