2011-07-20 23 views
30

Tôi có một thiết lập khá cơ bản với một UINavigationController bên trong một UITabBarController. Tôi muốn lập trình bố trí quan điểm của rootViewController của navcontroller đó, nhưng khi tôi nhìn vào bên trong self.view.frame viewDidLoad, tôi có được điều này (trong cảnh quan, ví dụ):Tại sao tôi phải đặt khung của chế độ xem của tôi theo cách thủ công trong viewDidLoad?

1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode 

Sau đó, tôi dừng quay để Portrait, và tôi có được điều này:

2. view frame: {{0, 0}, {768, 911}} 

sau đó, khi tôi quay trở lại phong cảnh, khung giờ này:

3. view frame: {{0, 0}, {1024, 655}} 

Và các sự kiện autorotation tiếp theo sẽ lật ngược giữa các giá trị khung hình # 2 & # 3.

Để khắc phục sự kì quái của # 1, tôi đang làm điều này trong viewDidLoad:

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
    self.view.frame = CGRectMake(0, 0, 768, 911); 
} else { 
    self.view.frame = CGRectMake(0, 0, 1024, 655); 
} 

Tôi cảm thấy như tôi rõ ràng là thiếu một cái gì đó ở đây. Tại sao khung mặc định của chế độ xem không khớp với khung khi nó tự động quay về cùng một hướng? Khung xem có được đặt thành hướng ban đầu không? Rất bối rối ...

Tôi nên đề cập đến không có điều nào ở trên, kể cả hack kludgy của tôi, thay đổi mọi thứ một cách trực quan. Lý do tôi có hack là khi tôi bố trí các bài đánh giá của tôi vào chế độ xem này, chúng sẽ dựa trên vị trí tôi mong đợi, đó là góc trên bên trái ngay dưới thanh điều hướng.

Tôi đang làm gì sai?

UPDATE: tắt tất cả những thứ autosizing về những thay đổi quan điểm dẫn # 1 là:

view frame: {{0, 0}, {748, 1024}} 

Đó có vẻ hơi nhỏ xíu gần hơn, nhưng vẫn không phù hợp với # 3.

Trả lời

96

Khung không được bảo đảm là như nhau trong viewDidLoad vì nó sẽ là khi quan điểm là cuối cùng được hiển thị. UIKit điều chỉnh khung của khung nhìn của trình điều khiển khung nhìn của bạn trước khi hiển thị nó, dựa trên ngữ cảnh trong đó sẽ xuất hiện. Kích thước được xác định dựa trên hướng giao diện và kích thước của bất kỳ thanh điều hướng hiển thị, thanh tab, thanh công cụ hoặc thanh trạng thái nào (chính nó có chiều cao có thể thay đổi, ví dụ: khi bạn đang gọi điện thoại).

Nó giúp để hiểu những gì sẽ xảy ra khi xem một cái nhìn khiển được nạp và hiển thị:

  1. Something truy cập tài sản view điều khiển quan điểm của bạn cho lần đầu tiên.Điều này có thể xảy ra trong mã của riêng bạn hoặc trong UIKit để phản hồi lại hành động của người dùng như chọn tab.

  2. UIKit tải chế độ xem của bộ điều khiển chế độ xem xuống bằng cách gọi loadView nếu được xác định hoặc bằng cách tải chế độ xem từ NIB được chỉ định trong initWithNibName:bundle:. Nếu không tồn tại, UIKit chỉ tải một khung nhìn rỗng.

  3. Cuộc gọi UIKit viewDidLoad khi chế độ xem và các bản xem phụ của nó đã được tải đầy đủ. Tại thời điểm này, khung của khung nhìn sẽ được đặt thành bất kỳ giá trị nào được đặt trong NIB hoặc trong loadView.

  4. Có gì đó yêu cầu UIKit hiển thị chế độ xem của bộ điều khiển chế độ xem. Một lần nữa, điều này có thể là hành động của người dùng như nhấn vào tab hoặc gọi phương thức rõ ràng trong mã của bạn như pushViewController:animated: hoặc presentModalViewController:animated:.

  5. UIKit định lại kích thước chế độ xem dựa trên ngữ cảnh mà nó sẽ được trình bày, như được mô tả ở trên.

  6. Cuộc gọi UIKit viewWillAppear:. Khung giờ sẽ là kích thước sẽ được hiển thị.(?) CHỈNH SỬA: Điều này có thể không còn đúng nữa. Xem các bình luận bên dưới.

  7. UIKit hiển thị chế độ xem, có hoặc không có hoạt ảnh.

  8. Cuộc gọi UIKit viewDidAppear:.

Như bạn có thể thấy, nếu bạn cần biết kích thước khung của khung nhìn trước khi được hiển thị, viewWillAppear: là cơ hội duy nhất của bạn. Chỉ cần nhớ rằng kích thước này có thể thay đổi sau khi chế độ xem xuất hiện vì nhiều lý do khác nhau, bao gồm các sự kiện xoay vòng hoặc thay đổi về chiều cao thanh trạng thái. Vì lý do này, điều quan trọng là cung cấp cho mọi subview một autoresizingMask thích hợp, để đảm bảo rằng bố cục có thể điều chỉnh chính nó cho bất kỳ thay đổi nào trong giới hạn.

Nếu bạn muốn xây dựng cấu trúc phân cấp chế độ xem của mình theo cách thủ công, địa điểm được đề xuất để làm như vậy là trong chế độ xem tải. Vì bạn tự xây dựng khung nhìn trong phương thức này, bạn có thể khởi tạo khung của nó theo bất cứ thứ gì bạn muốn. Kích thước bạn chọn không quan trọng lắm, vì UIKit có khả năng sẽ thay đổi nó theo bạn. Chỉ cần đảm bảo bạn đặt autoresizingMask của mình một cách thích hợp.

+0

Tôi có một câu hỏi về số câu trả lời của bạn 3. Tôi đã thử thiết lập xem trong tập tin nib, nhưng trong viewDidLoad khung nhìn của tôi không phải là những gì tôi đã được thiết lập trong Nib. Tôi đã đăng câu hỏi của tôi ở đây http://stackoverflow.com/q/7266177/147564 – sarunw

+14

Lạ lẫm, chế độ xem của tôi không có khung chính xác cho đến khi khung 8 'viewDidAppear: ' –

+13

có sẵn trong' '' viewDidLayoutSubviews''' trong iOS 5.0+ – Jon

-7

Sẽ có một phương pháp trong lớp học của bạn

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    // Return YES for supported orientations return YES; } 

Đặt khung hình của bạn trong phương pháp này ... Sau đó, nó sẽ hoạt động tốt.

Ví dụ:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
     // Return YES for supported orientations  
     if(interfaceOrientation == UIDeviceOrientationPortrait || UIDeviceOrientationPortraitUpsideDown) 
       self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinPOTRAIT, FRAME.HEIGHTinPOTRAIT); 
     else if(interfaceOrientation == UIDeviceOrientationLandscapeRight || UIDeviceOrientationLandscapeLeft) 
       self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinLANDSCAPE, FRAME.HEIGHTinLANDSCAPE); 

     return YES; 
} 

FRAME.WIDTH> mong muốn chiều rộng FRAME.HEIGHT> chiều cao mong muốn

+2

Thay đổi kích thước 'self.view' trong' shouldAutorotate' chính xác là những gì tài liệu UIKit nói không làm. – cbowns

+0

Đây là một mẹo bẩn – AlKozin

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