2009-04-08 38 views
7

Tôi muốn thực hiện như sau. Khi người dùng quay iPhone, tôi muốn tạo một UIViewController mới (tự động khi xoay, không nhấp vào nút hoặc thực hiện một hành động tương tự) và hiển thị cho người dùng chế độ xem được xử lý bởi UIViewController mới này ở hướng ngang. Làm thế nào để làm điều này đúng cách?Xoay iPhone và khởi tạo UIViewController mới?

Tôi đã cố gắng khởi tạo bộ điều khiển mới trong các phương thức willRotateToInterfaceOrientation và didRotateFromInterfaceOrientation, nhưng không có phương thức nào được gọi là !. Tôi nghi ngờ điều này là bởi vì bộ điều khiển hiện tại được đẩy vào bởi một bộ điều khiển chuyển hướng mà chính nó được xử lý bởi một tabBarController. Bất kỳ đầu mối? Một đoạn mã đơn giản sẽ được đánh giá cao.

Cảm ơn bạn trước.

Trả lời

7

Tôi đã triển khai kiểu hành vi chính xác này trên một ứng dụng và điều quan trọng là đảm bảo rằng bất kỳ bộ điều khiển cha mẹ nào thực hiện shouldAutorotateToInterfaceOrientation và trình điều khiển chế độ xem hiện tại của bạn cũng thực hiện nó. Trong trường hợp của tôi tôi đang sử dụng một bộ điều khiển tab mà chặn các cuộc gọi đến shouldAutorotateToInterfaceOrientation và tôi đã phải ghi đè lên bộ điều khiển tab để có được cuộc gọi để giảm qua. Hành vi mặc định của bộ điều khiển chế độ xem chỉ hiển thị ở chế độ dọc.

Vì vậy, bạn cần buộc chúng cho phép tất cả các thay đổi định hướng thông qua: - (BOOL) shouldAutorotateToInterfaceĐối tượng: (UIInterfaceOrientation) interfaceĐối tượng { trả về CÓ; }

Sau đó, để tải một bộ điều khiển xem mới, bạn nên đáp lại:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) || 
    (fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)) 
    {  
    // Load the view controller you want to display in landscape mode... 
    } 
} 

và cũng có thể sử dụng:

-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

Để phát hiện rằng sự thay đổi định hướng được tới.

Trong trường hợp của tôi, tôi đang sử dụng didRotateFromInterfaceOrientation để kiểm tra xem định hướng cuối cùng có phải là dọc hay không và nếu tải chế độ xem tôi muốn hiển thị ở chế độ ngang.

Sau đó, tôi đã triển khai các phương thức giống nhau trong trình điều khiển chế độ xem mà tôi đang tải và nó chịu trách nhiệm phát hiện khi định hướng thay đổi về chân dung và loại bỏ chính nó khỏi khung nhìn.

Hy vọng rằng sẽ giúp ích một chút.

Paul

+0

Tôi có cần phân lớp tabBarController ban đầu để thêm phương thức shouldAutorotateToInterfaceOrientation vào nó không? Bộ điều khiển tabBar này đã được thiết lập bằng cách sử dụng IB và một vài dòng mã trong ủy nhiệm ứng dụng. Tôi đã làm theo tất cả các bước, nhưng didRotateFromInterfaceOrientation không được gọi. –

+1

Ok, tôi đã phân lớp tabBarController, thêm shouldAutorotateToInterfaceOrientation và bây giờ mọi thứ hoạt động. Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn. Trân trọng. –

+0

Tôi không thích sử dụng UITabBarController ở tất cả và thay vào đó sử dụng UIViewController với UITabBar. – mk12

1

Bạn có triển khai shouldAutorotateToInterfaceOrientation không? Nếu không, thì đó có thể là lý do tại sao bạn không nhận được tin nhắn.

+0

Có, tôi làm. Thậm chí chỉ cần trả về YES trong shouldAutorotateToInterfaceOrientation không hoạt động. –

29

Cách sạch hơn là KHÔNG sử dụng UIInterfaceĐối với vòng quay.

Lý do, vì sau đó giao diện hoặc chế độ xem của bạn thực sự quay. Điều này có nghĩa là bạn phải xoay nó lại để hiển thị lại sau khi xem 2 bị xóa.

Để bù lại điều này, tôi đơn giản đăng ký Thông báo UIDeviceOrientation. Subtly khác nhau. View 1 KHÔNG phải hỗ trợ autorotation để làm cho phương thức này hoạt động.Trong viewDidLoad nhập đoạn mã sau:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectOrientation) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; 

Sau đó chỉ cần xác định phương pháp detectOrientation:

-(void) detectOrientation { 

    if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) || 
      ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) { 

     //load view 2 


    } else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) { 

     // load view 1 

    } 
} 

Bây giờ không phải quan điểm của bạn cần hỗ trợ autoratation! Tuy nhiên, bạn sẽ cần phải thực hiện chuyển đổi trên chế độ xem 2 trước khi tải:

-(void) transformView2ToLandscape { 

    NSInteger rotationDirection; 
    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation]; 

    if(currentOrientation == UIDeviceOrientationLandscapeLeft){ 
    rotationDirection = 1; 
    }else { 
    rotationDirection = -1; 
    } 

    CGRect myFrame = CGRectMake(0, 0, 480, 300); 
    CGAffineTransform transform = [[self view2] transform]; 
    transform = CGAffineTransformRotate(transform, degreesToRadians(rotationDirection * 90)); 
    [[self view2] setFrame: myFrame]; 
    CGPoint center = CGPointMake(myFrame.size.height/2.0, myFrame.size.width/2.0); 
    [[self view2] setTransform: transform]; 
    [[self view2] setCenter: center]; 

} 

Thats cách tôi hoán đổi chế độ xem xoay vòng mà không hỗ trợ tự động ghi lại trong chế độ xem của tôi.

+1

Điều này trông thực sự thú vị. Tôi sẽ cố gắng hiểu hiệu suất thực tế, tức là, thông báo được phân phối nhanh hơn bao nhiêu và phải mất bao nhiêu để áp dụng biến đổi. Cảm ơn bạn rất nhiều. –

+0

hoạt động rất tốt. đặc biệt nếu bạn đang sử dụng hai bộ điều khiển xem khác nhau cho hai hướng. –

+0

Câu trả lời "đã chọn" trả lời câu hỏi, nhưng câu trả lời này trả lời câu hỏi (lý tưởng) nên được hỏi. – DBD

3

Thực tế chỉ có trình điều khiển cấp cao nhất mới được thông báo. Bạn chịu trách nhiệm thông báo cho bộ điều khiển lồng nhau.

Thêm này để điều khiển thanh tab của bạn:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    [self.selectedViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
} 
+0

Cảm ơn bạn, tôi sẽ thêm mã này vào mã của tôi. –

+0

Bạn không nên phân lớp UITabBarController. – mk12

+0

@ Mk12: Tại sao? Có thể ghi đè lên các vấn đề nhỏ như vậy? – Kornel

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