13

Tôi có bộ điều khiển điều hướng có một vài bộ điều khiển chế độ xem. Tôi cần hỗ trợ tất cả các định hướng cho tất cả các bộ điều khiển xem ngoại trừ một bộ điều khiển xem đặc biệt chỉ hỗ trợ chế độ ngang. Bộ điều khiển xem đặc biệt này xuất hiện ở giữa ngăn xếp điều hướng. Tôi đã thực hiện khá nhiều nghiên cứu nhưng không thể tìm ra giải pháp tốt nào. Dưới đây là các liên kết mà tôi đã đọc và thử.Hỗ trợ cảnh quan chỉ cho một chế độ xem trong UINavigationController

http://www.iphonedevsdk.com/forum/iphone-sdk-development/3219-force-landscape-mode-one-view.html#post60435

How to rotate screen to landscape?

How to autorotate from portrait to landscape mode? iPhone - allow landscape orientation on just one viewcontroller http://goodliffe.blogspot.com/2009/12/iphone-forcing-uiview-to-reorientate.html

Tiếp theo tôi sẽ cố gắng để thay thế điều khiển chuyển hướng với presentModalViewController để hiển thị điều khiển xem đặc biệt. Sau đó, tôi sẽ tạo một bộ điều khiển xem điều hướng mới bên trong bộ điều khiển xem đặc biệt để đẩy các bộ điều khiển xem tiếp theo.

Nếu có ai có ý tưởng hay hơn, vui lòng cho tôi biết. Rất cảm kích!

CẬP NHẬT: Tôi đã sử dụng thành công phương pháp tôi đã mô tả ở trên: thay thế pushViewController bằng presentModalViewController và tạo bộ điều khiển điều hướng mới.

+0

bạn có thể chia sẻ mã mẫu không? –

Trả lời

8

Mỗi cái nhìn cũ đẩy lên điều hướng điều khiển ngăn xếp phải hỗ trợ các định hướng tương tự. Điều này có nghĩa là không thể có một số bộ điều khiển xem chỉ hỗ trợ ảnh chân dung và các bộ điều khiển khác chỉ hỗ trợ cảnh quan.Nói cách khác, tất cả các bộ điều khiển chế độ xem trên cùng một ngăn điều khiển điều hướng phải trả lại như nhau trong ủy quyền:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

Nhưng có một giải pháp đơn giản cho điều này! Đây là một ví dụ để đi từ chân dung đến phong cảnh. Đây là các bước để làm điều đó và dưới đây là mã để hỗ trợ nó.

  1. Tạo bộ điều khiển chế độ xem ‘giả mạo’ sẽ nằm trong trình điều khiển điều hướng phụ. Bộ điều khiển xem này sẽ hỗ trợ cảnh quan.
  2. Tạo một thể hiện mới của một UINavigationController, thêm một thể hiện của quan điểm điều khiển 'giả' root và một thể hiện của điều khiển xem phong cảnh của bạn như xem thứ hai điều khiển
  3. Trình bày dụ UINavigationController như phương thức từ bộ điều khiển xem mẹ

Đầu tiên, tạo một bộ điều khiển xem mới (FakeRootViewController) với mã này:

@interface FakeRootViewController : UIViewController 
@property (strong, nonatomic) UINavigationController* parentNavigationController; 
@end 

@implementation FaceRootViewController 
@synthesize parentNavigationController; 
// viewWillAppear is called when we touch the back button on the navigation bar 
(void)viewWillAppear:(BOOL)animated { 
    // Remove our self from modal view though the parent view controller 
    [parentNavigationController dismissModalViewControllerAnimated:YES]; 
} 
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); 
} 

Dưới đây là đoạn code để trình bày các điều khiển xem mà bạn muốn hiển thị trong chế độ nằm ngang:

FakeRootViewController* fakeRootViewController = [[FakeRootViewController alloc] init];[fakeRootViewController.navigationItem setBackBarButtonItem:backButton]; // Set back button 
// The parent navigation controller is the one containing the view controllers in portrait mode. 
fakeRootViewController.parentNavigationController = parentNavigationController; 

UINavigationController* subNavigationController = // Initialize this the same way you have initialized your parent navigation controller. 

UIViewController* landscapeViewController = // Initialize the landscape view controller 

[subNavigationController setViewControllers: 
    [NSArray arrayWithObjects:fakeRootViewController, 
               landscapeViewController, nil] animated:NO]; 

[_navigationController presentModalViewController:subNavigationController animated:YES]; 

Hãy nhớ rằng landscapeViewController cũng cần phải có thực hiện điều này:

(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return (interfaceOrientation == UIInterfaceOrientationIsLandscape(interfaceOrientation)); 
} 
+1

+50 amazeballs. – Adam

+0

Cuối cùng là một câu trả lời thẳng. – Jeef

0

Nó phải là đơn giản như thực hiện

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

trong mỗi UIViewController đẩy vào UINavigationController của bạn. Trong trường hợp một chế độ xem của UIViewController không được xoay, return NO cho hướng cụ thể đó trong số UIViewController cụ thể đó. Có một Gotcha đây tuy nhiên, nếu bạn thực hiện UINavigationController

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

nó sẽ chặn viewControllers từ nhận phương pháp đó. Trong trường hợp đó, bạn nên chuyển tiếp thông điệp tới topViewController sử dụng

[[self topViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
+3

Tôi ước nó đơn giản. Bạn đã thử chưa Có một vài vấn đề với điều đó. 1. nếu bạn hiển thị chế độ xem phong cảnh đặc biệt khi điện thoại ở chế độ dọc, khi bạn xoay điện thoại thành ngang, chế độ xem sẽ xoay sang chân dung bất ngờ. 2. khi bạn hiển thị chế độ xem phong cảnh đặc biệt lần đầu tiên, sau đó xoay điện thoại thành dọc, sau đó thoát chế độ xem đặc biệt và nhập lại, chế độ xem được xoay bất ngờ. Điều này có vẻ giống như một vấn đề với bộ điều khiển điều hướng và tôi thực sự muốn Apple có thể làm cho nó hoạt động cho những gì bạn mô tả. –

+0

Tôi đã thử nó. Tôi nghĩ rằng các vấn đề bạn đang gặp phải có thể là cụ thể đối với đơn đăng ký của bạn. Hãy thử bắt đầu một dự án mới để cô lập vấn đề xoay UINavigationController, sau đó chạy một số thử nghiệm. – schellsan

0

Bạn có thể thử mã này trong UINavigationController của bạn để gọi xem có thể nhìn thấy của shouldAutorotateToInterfaceOrientation hiện hành. Trong trường hợp của tôi, tôi có số UINavigationController trong một số UITabBarController nhưng bạn có thể thích ứng với các trường hợp khác.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if ([appDelegate.tabBarController.selectedViewController respondsToSelector:@selector(topViewController)]) 
    { 
     UINavigationController *nc = (UINavigationController*)appDelegate.tabBarController.selectedViewController; 
     return [nc.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
    } 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 
0

Bạn có thể thực hiện hành động: Thay đổi mã của bạn với theo của đề nghị schellsan, bên cạnh - Cố gắng thêm currentViewController (mà sẽ đẩy tới điều hướng viewController) như tài sản để appdelegate. Khi bạn cố gắng để đẩy bộ điều khiển xem, đặt nó vào bộ điều khiển xem hiện tại trước khi điều này. Tiếp theo - tạo một lớp con của rootViewController trong bộ điều khiển điều hướng. Trong lớp con này phương pháp owerload

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    // Overriden to allow any orientation. 
    return [appDelegate.currentViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation]; 
} 

Nó nên hoạt động nếu bạn không sử dụng một thanh điều hướng và đẩy điều khiển mới sau khi popping một bộ điều khiển

+3

Làm thế nào để bạn đạt được điều tương tự với phiên bản iOS 6 .. – Krishnan

1

Có một API riêng để buộc một thay đổi hướng. Đặt trong đẩy quan điểm điều khiển của bạn -viewWillAppear::

if ([UIDevice instancesRespondToSelector:@selector(setOrientation:)]) { 
    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait]; 
} 

Để ngăn chặn các cảnh báo trình biên dịch, thêm video này vào file .m của bộ điều khiển xem của bạn:

@interface UIDevice() 
- (void)setOrientation:(UIDeviceOrientation)orientation; // private API to let POIEntryVC be pushed over landscape route view 
@end 

Như mọi khi, có một nguy cơ bị từ chối và có nguy cơ phá vỡ các phiên bản hệ điều hành trong tương lai khi sử dụng API riêng tư. Làm nguy cơ của riêng bạn!

Nói chung, trình bày bộ điều khiển chế độ xem là giải pháp tốt hơn trong hầu hết các trường hợp.

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