iOS 6: Làm cách nào để hạn chế một số chế độ xem ở chế độ dọc và cho phép những chế độ khác xoay?


99

Tôi có một ứng dụng iPhone sử dụng a UINavigationControllerđể trình bày giao diện chi tiết: Đầu tiên là một chế độ xem, sau đó là một chế độ xem khác, sâu đến bốn cấp độ. Tôi muốn ba chế độ xem đầu tiên bị hạn chế ở hướng dọc và chỉ chế độ xem cuối cùng mới được phép xoay sang hướng ngang. Khi quay trở lại từ chế độ xem thứ tư sang chế độ xem thứ ba và chế độ xem thứ tư theo hướng ngang, tôi muốn mọi thứ xoay trở lại theo chiều dọc.

Trong iOS 5, tôi chỉ cần xác định shouldAutorotateToInterfaceOrientation:trong mỗi bộ điều khiển chế độ xem của mình để trả về CÓ cho các hướng cho phép. Mọi thứ hoạt động như mô tả ở trên, bao gồm cả việc quay lại chế độ dọc ngay cả khi thiết bị đang được giữ ở hướng ngang khi quay trở lại từ bộ điều khiển chế độ xem # 4 đến # 3.

Trong iOS 6, tất cả các bộ điều khiển chế độ xem đều xoay theo chiều ngang, phá vỡ những bộ điều khiển không cố ý. Ghi chú phát hành iOS 6 cho biết

Nhiều trách nhiệm hơn đang chuyển sang ứng dụng và đại biểu ứng dụng. Giờ đây, các vùng chứa iOS (chẳng hạn như UINavigationController) không hỏi ý kiến ​​con cái của họ để xác định xem chúng có nên tự động chuyển động hay không. [...] Hệ thống hỏi bộ điều khiển chế độ xem toàn màn hình trên cùng (thường là bộ điều khiển chế độ xem gốc) về các hướng giao diện được hỗ trợ của nó bất cứ khi nào thiết bị xoay hoặc bất cứ khi nào bộ điều khiển chế độ xem được trình bày với kiểu trình bày phương thức toàn màn hình. Hơn nữa, các hướng được hỗ trợ chỉ được truy xuất nếu bộ điều khiển chế độ xem này trả về CÓ từ shouldAutorotatephương thức của nó . [...] Hệ thống xác định xem định hướng có được hỗ trợ hay không bằng cách giao giá trị được trả về bởi supportedInterfaceOrientationsForWindow:phương thức của ứng dụng với giá trị được trả về bởi supportedInterfaceOrientationsphương thức của bộ điều khiển toàn màn hình trên cùng.

Vì vậy, tôi đã phân lớp con UINavigationController, cho thuộc MainNavigationControllertính boolean của mình landscapeOKvà sử dụng thuộc tính này để trả về các định hướng cho phép trong supportedInterfaceOrientations. Sau đó, trong mỗi viewWillAppear:phương pháp của bộ điều khiển chế độ xem của tôi, tôi có một dòng như thế này

    [(MainNavigationController*)[self navigationController] setLandscapeOK:YES];

để cho biết MainNavigationControllerhành vi mong muốn của tôi .

Đây là câu hỏi: Nếu bây giờ tôi điều hướng đến chế độ xem thứ tư của mình ở chế độ dọc và lật điện thoại lên, nó sẽ xoay ngang. Bây giờ tôi nhấn nút quay lại để quay lại chế độ xem thứ ba được cho là chỉ hoạt động ở chế độ dọc. Nhưng nó không xoay trở lại. Làm thế nào để tôi làm cho nó làm điều đó?

Tôi đã thử

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]

trong viewWillAppearphương thức của bộ điều khiển chế độ xem thứ ba của tôi, nhưng nó không làm gì cả. Đây có phải là phương pháp gọi sai hoặc có thể gọi sai chỗ hay tôi nên triển khai toàn bộ nội dung theo một cách hoàn toàn khác?

Câu trả lời:


95

Tôi đã gặp vấn đề tương tự và đã tìm thấy một giải pháp phù hợp với tôi. Để làm cho nó hoạt động, chỉ cần triển khai trong UINavigationController của bạn là chưa đủ - (NSUInteger)supportedInterfaceOrientations. Bạn cũng cần triển khai phương pháp này trong bộ điều khiển số 3 của mình, đây là phương pháp đầu tiên chỉ ở chế độ dọc sau bộ điều khiển bật lên số 4. Vì vậy, tôi có mã sau trong UINavigationController của mình:

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if (self.isLandscapeOK) {
        // for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

Trong bộ điều khiển chế độ xem # 3, thêm phần sau:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

Bạn không cần thêm bất kỳ thứ gì vào bộ điều khiển chế độ xem # 1, # 2 và # 4. Điều này làm việc cho tôi, tôi hy vọng nó sẽ giúp bạn.


8
bạn đã giải quyết một cái gì đó mà mọi người đã cố gắng giải quyết trong nhiều tháng! bạn xứng đáng nhận được rất nhiều tín dụng cho điều này! Tôi đã thêm supportsInterfaceOrientations vào một danh mục trên UIViewController và nó hoạt động hoàn hảo như một mặc định cho những bộ điều khiển chỉ dọc đó.
dwery 26/10/12

3
Trong số 100 câu trả lời khác nhau trên SO, đây là câu trả lời thực sự hiệu quả. Cảm ơn :-)
Christer Nordvik

16
Tôi đã thiết lập điều này và vẫn nhận được định hướng sai khi quay LẠI từ chế độ dọc sang bộ điều khiển chế độ xem bị giới hạn ở chế độ chỉ ngang. Nó không tự động chuyển động theo phong cảnh - Có ai khác vẫn nhìn thấy nó không?
Oded Ben Dov

1
điều gì sẽ xảy ra nếu bộ điều khiển chế độ xem phong cảnh mong muốn đang được trình bày từ một segue và không có bộ điều khiển điều hướng?
jesses.co.tt

1
Chỉnh sửa cái cuối cùng thành NSUInteger làm kiểu trả về.
vắng mặt

68

Thêm một CustomNavigationController

Ghi đè các phương thức này trong đó:

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

Bây giờ hãy thêm tất cả các hướng trong plist

nhập mô tả hình ảnh ở đây

Trong bộ điều khiển chế độ xem chỉ thêm những cái bắt buộc:

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

các phương pháp này ghi đè các phương thức của bộ điều khiển điều hướng


5
Bạn thực sự đóng đinh nó với câu trả lời này! Cảm ơn bạn rất nhiều. Bạn thực sự đã giúp đỡ rất nhiều. Đây là một vấn đề lớn đối với tôi trong một thời gian. Bạn đã làm rất tốt.
K2Digital

Cảm ơn bạn! Điều này khiến tôi mất rất nhiều thời gian và năng lượng để tìm ra!
bkbeachlabs

Bạn là người cứu rỗi cuộc sống .... Điều này cũng hoạt động trong ứng dụng của tôi. Trên thực tế, những gì tôi muốn trong ứng dụng của mình là tôi có tất cả ViewControllerđều ở chế độ Chân dung và cái của tôi ViewControllerở chế độ Landscap & Chân dung. Tôi cũng hỗ trợ cả iOS 5.0 và iOS 6.0 Đó là lý do tại sao tôi bối rối để làm việc xung quanh nhưng đây là giải pháp tuyệt vời. tôi thêm CustomNavigationController trong bộ điều khiển chế độ xem gốc của mình và cung cấp hỗ trợ theo nhu cầu của tôi. Một lần nữa xin cảm ơn.
Bhavin_m

Tuyệt diệu. Chính xác những gì tôi cần. Cảm ơn bạn.
mszaro

điều gì sẽ xảy ra nếu bộ điều khiển chế độ xem phong cảnh mong muốn đang được trình bày từ một segue và không có bộ điều khiển điều hướng?
jesses.co.tt

9

Sau khi xem qua từng câu trả lời trong vô số câu hỏi tương tự trên SO, không câu trả lời nào phù hợp với tôi, nhưng chúng đã cho tôi một số ý tưởng. Đây là cách tôi đã giải quyết vấn đề:

Trước tiên, hãy đảm bảo rằng Định hướng giao diện được hỗ trợ của bạn trong mục tiêu của dự án chứa tất cả các hướng mà bạn muốn cho chế độ xem xoay vòng của mình.

nhập mô tả hình ảnh ở đây

Tiếp theo, tạo một danh mục UINavigationController (vì Apple nói rằng không phân loại nó):

@implementation UINavigationController (iOS6AutorotationFix)

-(BOOL)shouldAutorotate {
    return [self.topViewController shouldAutorotate];
}

@end

Nhập danh mục đó và bộ điều khiển chế độ xem mà bạn muốn có thể xoay (mà tôi sẽ gọi RotatingViewController) vào bộ điều khiển chế độ xem cấp cao nhất của bạn, bộ điều khiển này sẽ chứa bộ điều khiển điều hướng của bạn. Trong bộ điều khiển chế độ xem đó, triển khaishouldAutorotate như sau. Lưu ý rằng đây không phải là bộ điều khiển chế độ xem mà bạn muốn xoay.

-(BOOL)shouldAutorotate {

    BOOL shouldRotate = NO;

    if ([navigationController.topViewController isMemberOfClass:[RotatingViewController class]] ) {
        shouldRotate = [navigationController.topViewController shouldAutorotate];
    }

    return shouldRotate;
}

Cuối cùng, trong của bạn RotatingViewController, triển khai shouldAutorotatesupportedInterfaceOrientationsnhư sau:

-(BOOL)shouldAutorotate {
    // Preparations to rotate view go here
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown; // or however you want to rotate
}

Lý do bạn cần làm điều này là vì iOS 6 cung cấp quyền kiểm soát xoay cho bộ điều khiển chế độ xem gốc thay vì bộ điều khiển chế độ xem trên cùng. Nếu bạn muốn xoay vòng của một dạng xem riêng lẻ hoạt động khác với các dạng xem khác trong ngăn xếp, bạn cần viết một trường hợp cụ thể cho nó trong bộ điều khiển chế độ xem gốc.


2
Đây là một câu trả lời xuất sắc đáng được yêu thích hơn. Đây là phần thông tin mà nó chứa mà tôi không thể tìm thấy ở bất kỳ nơi nào khác và điều quan trọng: Nếu bạn muốn xoay vòng của một chế độ xem riêng lẻ hoạt động khác với các chế độ xem khác trong ngăn xếp, bạn cần phải viết một trường hợp cụ thể cho nó trong thư mục gốc xem bộ điều khiển
shmim

Tôi cho rằng điều này sẽ hoạt động nếu bạn có navigationController là thành viên đầu tiên trong bảng phân cảnh của ứng dụng làm bộ điều khiển ban đầu nhưng còn trường hợp khi bộ điều khiển ban đầu chỉ đơn giản là ViewController thì sao?
Duck

4

Tôi không có đủ danh tiếng để bình luận về câu trả lời của @ Brian nên tôi sẽ thêm ghi chú của mình ở đây.

Brian đã đề cập rằng iOS6 cung cấp quyền kiểm soát xoay vòng cho rootViewController - đây không chỉ có thể là một UINavigationController như đã đề cập mà còn là một UITabBarController, nó dành cho tôi. Cấu trúc của tôi trông như thế này:

  • UITabBarController
    • UINavigationController
      • UIViewControllers ...
    • UINavigationController
      • UIViewControllers ...

Vì vậy, trước tiên tôi đã thêm các phương thức vào UITabBarController tùy chỉnh, sau đó trong UINavigationController tùy chỉnh và cuối cùng là trong UIViewController cụ thể.

Ví dụ từ UITabBarController và UINavigationController:

- (BOOL)shouldAutorotate {
    return [self.viewControllers.lastObject shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations {
    return [self.viewControllers.lastObject supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return [self.viewControllers.lastObject shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}

Tôi thực sự đã sử dụng UITabBarController làm biến phiên bản trong bộ điều khiển chế độ xem gốc của mình vì bạn không phải phân lớp UITabBarController trong các phiên bản iOS trước 6.0 và tôi cần hỗ trợ trở lại iOS 5.0.
Brian

@micmdk Tôi có cùng một vấn đề. vui lòng tư vấn cách giải quyết, tôi đã sao chép mã của bạn và đưa vào Bộ điều khiển điều hướng tùy chỉnh và Bộ điều khiển tùy chỉnhUabbarController và đặt bộ điều khiển chế độ xem khác là Brian's Guided. nhưng vẫn không nhận được bộ điều khiển chế độ xem cố định ở chế độ dọc.
Ram S

@Brian Tôi có cùng một vấn đề. vui lòng cho biết cách giải quyết, tôi đã sao chép mã của bạn và đưa vào Bộ điều khiển điều hướng tùy chỉnh và Bộ điều khiển tùy chỉnhUabbarController và đặt bộ điều khiển chế độ xem khác làm Hướng dẫn của Micmdk. nhưng vẫn không nhận được bộ điều khiển chế độ xem cố định ở chế độ dọc trong ios8.
Ram S

3

Tôi muốn trả lời một phần cho câu hỏi của riêng tôi. Tôi tìm thấy dòng mã sau, được sử dụng trong viewWillAppearphương pháp thứ ba của tôi UIViewController, hoạt động:

[[UIDevice currentDevice] 
      performSelector:NSSelectorFromString(@"setOrientation:") 
           withObject:(id)UIInterfaceOrientationPortrait];

Nhưng tôi không thực sự thích giải pháp này. Nó đang sử dụng một thủ thuật để gán cho thuộc tính chỉ đọc mà theo tài liệu của Apple thể hiện hướng vật lý của thiết bị. Nó giống như yêu cầu iPhone nhảy đến đúng hướng trong tay người dùng.

Tôi rất muốn để nó trong ứng dụng của mình vì nó chỉ hoạt động. Nhưng cảm thấy không ổn nên tôi muốn bỏ ngỏ câu hỏi để có một giải pháp rõ ràng.


4
Ứng dụng của bạn rất có thể sẽ bị từ chối nếu bạn để nó ở đó. Tôi cũng đang tìm giải pháp cho vấn đề này, nhưng có vẻ như không thể. Tất cả tôi có thể tìm được câu trả lời cho câu hỏi này: stackoverflow.com/questions/7196300/... nó loại công trình nhưng vì một lý do nó phá vỡ xử lý cảm ứng nút trong một trong viewcontrollers tôi
Lope

Tôi đã tận dụng cơ hội của mình và nộp cho Apple. Vẫn đang chờ xem xét ... Tôi sẽ tiếp tục đăng cho bạn.
Harald Bögeholz

Apple vừa phê duyệt ứng dụng của tôi với bản hack này tại chỗ, yey! Tôi hy vọng nó sẽ không phản tác dụng với tôi trong bản cập nhật iOS trong tương lai. Trong thời gian chờ đợi, tôi vẫn sẵn sàng nhận các đề xuất về giải pháp sạch!
Harald Bögeholz

1
@ HaraldBögeholz Grt kích hoạt. nhưng khi tôi làm việc trong xCode mới với ARC hơn tôi không thể sử dụng ans. Tôi nhận được "Truyền của NSInteger (còn gọi là int) tới id không được phép với ARC PerformSelector có thể gây ra rò rỉ vì bộ chọn của nó không xác định" làm cách nào để giải quyết vấn đề này? Tôi thực sự cảm phục bạn nếu chúng tôi có giải pháp. Khi tôi tắt ARC cho Chế độ xem perticular thì ứng dụng gặp sự cố do một số dữ liệu bị rò rỉ. Vui lòng gợi ý cho tôi
Hitarth

4
Sử dụng API riêng KHÔNG BAO GIỜ là giải pháp.
Javier Soto

2

Đây là tôi đang sử dụng để hỗ trợ định hướng trong ios 6.0

-(BOOL)shouldAutorotate{
    return YES;
}  

 - (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskAll;
}


- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{  
  return UIInterfaceOrientationPortrait;
}

1

Vì đây là một chủ đề được xem nhiều. Tôi đã nghĩ rằng tôi sẽ thêm những gì tôi tin là câu trả lời dễ nhất. Điều này hoạt động cho ios8 trở lên

-(BOOL)shouldAutorotate
{
    return YES;
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Đó là nó. Thưởng thức!

Ồ, và các ViewControllers của tôi được nhúng trong một bộ điều khiển điều hướng, mà tôi không cần phải phân lớp hoặc định cấu hình theo bất kỳ cách nào.


0

Điều này có thể không hiệu quả với tất cả mọi người, nhưng nó rất hiệu quả đối với tôi. Thay vì thực hiện ...

[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];

trong viewWillAppear trong tất cả các bộ điều khiển của tôi, tôi quyết định tập trung quá trình này bên trong lớp con UINavigationController của mình bằng cách ghi đè phương thức UINavigationControllerDelegatenavigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {

    self.previousVCLandscapeOK = self.isLandscapeOK; // Store the current VC's orientation preference before pushing on the new VC so we can set this again from within the custom "back" method
    self.isLandscapeOK = NO; // Set NO as default for all VC's
    if ([viewController isKindOfClass:[YourViewController class]]) {
        self.isLandscapeOK = YES;
    }
}

Tôi nhận thấy rằng phương thức đại biểu này không được gọi khi bật một VC ra khỏi ngăn xếp điều hướng. Đây không phải là vấn đề đối với tôi vì tôi đang xử lý chức năng quay lại từ bên trong lớp con UINavigationController của mình để tôi có thể đặt các nút và hành động trên thanh điều hướng thích hợp cho các VC cụ thể như thế này ...

if ([viewController isKindOfClass:[ShareViewController class]]) {

    UIButton* backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 57, 30)];
    [backButton setImage:[UIImage imageNamed:@"back-arrow"] forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem* backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    viewController.navigationItem.leftBarButtonItem = backButtonItem;

    UIImageView* shareTitle = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"share-title"]];
    [shareTitle setContentMode:UIViewContentModeScaleAspectFit];
    [shareTitle setFrame:CGRectMake(0, 0, shareTitle.frame.size.width - 10, shareTitle.frame.size.height - 10)];
    viewController.navigationItem.titleView = shareTitle;

} else if(...) {
    ...
}

Đây là backphương pháp của tôi trông như thế nào để xử lý việc bật VC ra khỏi ngăn xếp và để đặt tùy chọn xoay vòng thích hợp ...

- (void)back {
    self.isLandscapeOK = self.previousVCLandscapeOK;
    self.previousVCLandscapeOK = NO;
    [self popViewControllerAnimated:YES];
}

Vì vậy, như bạn có thể thấy, về cơ bản tất cả những gì đang xảy ra là đầu tiên tôi đặt cho tôi hai thuộc tính ...

@property (nonatomic) BOOL isLandscapeOK;
@property (nonatomic) BOOL previousVCLandscapeOK;

trong navigationController:willShowViewController:animated:đó sẽ xác định những định hướng được hỗ trợ trong VC đó sắp được trình bày. Khi bật một VC, phương thức "quay lại" tùy chỉnh của tôi đang được gọi và sau đó tôi đang đặt isLandscapeOK thành những gì đã được lưu trữ thông qua giá trịVCLandscapeOK trước đó.

Như tôi đã nói, điều này có thể không hiệu quả với tất cả mọi người, nhưng nó hoạt động tốt với tôi và tôi không phải lo lắng về việc thêm mã vào từng bộ điều khiển chế độ xem của mình, tôi có thể giữ tất cả tập trung trong lớp con UINavigationController.

Hy vọng điều này sẽ giúp ai đó như tôi đã làm. Cảm ơn, Jeremy.



0

Bạn chỉ muốn Buộc dọc ứng dụng iOS 6 thì bạn có thể thêm vào lớp con UIViewController các phương thức bên dưới

- (BOOL)shouldAutorotate {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return NO;
    }
}


- (NSUInteger)supportedInterfaceOrientations {
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return UIInterfaceOrientationMaskAll;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}

2
Vấn đề là trừ khi chế độ xem đó là chế độ xem gốc (không có trong câu hỏi này), thì shouldAutorotate không được gọi.
Brian

vì bất cứ lý do gì trả về kiểu NSUIntegerném cảnh báo mặc dù nó là kiểu var chính xác. nếu bạn có OCD sử dụng UIInterfaceOrientationMaskthay thế.
Chris J

Ngoài ra, giải pháp này hoạt động hoàn hảo cho bộ điều khiển chế độ xem phương thức (chế độ xem camera) mà tôi có mà không cần phân lớp phụ UINavigationController. Tôi đoán các phương thức được đối xử độc lập. Không liên quan đến câu hỏi ban đầu, nhưng thông tin hữu ích để có thiết kế khôn ngoan.
Chris J

0

Tôi muốn khóa tất cả VC của mình theo hướng dọc ngoại trừ một. Đây là những gì làm việc cho tôi.

  1. Thêm hỗ trợ cho tất cả các hướng trong tệp plist.
  2. Trong bộ điều khiển chế độ xem gốc, hãy phát hiện loại bộ điều khiển chế độ xem nằm trên đầu cửa sổ và đặt hướng của ứng dụng tương ứng trong phương thức được hỗ trợInterfaceOrientations. Ví dụ: tôi cần ứng dụng của mình chỉ xoay khi chế độ xem web ở trên cùng của ngăn xếp. Đây là những gì tôi đã thêm vào rootVC của mình:

    -(NSUInteger)supportedInterfaceOrientations
    {
        UIViewController *topMostViewController = [[Utils getAppDelegate] appNavigationController].topViewController;
        if ([topMostViewController isKindOfClass:[SVWebViewController class]]) {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
        return UIInterfaceOrientationMaskPortrait;
    }

Trunal, Đây là một vài tháng tuổi nhưng bạn có thể cung cấp thêm một chút chi tiết về cách bạn phát hiện loại bộ điều khiển chế độ xem ở trên cùng không. Cụ thể, tôi không chắc chắn những gì bạn đã đi ở đây [[Utils getAppDelegate] appNavigationController]. Mặc dù tôi đoán là bạn có lớp nào đó nhưng tôi không biết bạn làm gì trong đó. Bất kỳ sự trợ giúp nào đều sẽ là tuyệt vời!
Ben

0

Tôi không có đủ danh tiếng để trả lời câu hỏi của @Ram S trong phần trả lời @micmdk nên tôi sẽ thêm ghi chú của mình ở đây.

Khi bạn sử dụng UITabbarController , hãy thử thay đổi self.viewControllers.lastObject trong mã của @ micmdk thành self.selectedViewController như thế này:

- (BOOL)shouldAutorotate {
    return [self.selectedViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations {
    return [self.selectedViewController supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return [self.selectedViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}

0

Bạn có thể triển khai và ghi đè nên var shouldAutorotate () và supportsInterfaceOrientations trong tất cả các lớp View Controller của bạn. Các lớp này sẽ được trình bày theo các hướng khác với các lớp được xác định trong PLIST của ứng dụng của bạn.

Tuy nhiên, trong một Giao diện người dùng tầm thường, bạn có thể gặp phải vấn đề khi thêm nó vào hàng chục lớp và bạn không muốn tạo tất cả chúng thành lớp con của một số lớp phổ biến hỗ trợ nó (MyBaseTableViewController, MyBaseNavigationController và MyBaseTabBarController).

Vì bạn không thể ghi đè phương thức / var đó trực tiếp trên UIViewController, bạn có thể thực hiện điều đó trên các lớp con của nó mà thường là các lớp cơ sở của bạn như UITableViewController, UINavigationController và UITabBarController.

Vì vậy, bạn có thể triển khai một số tiện ích mở rộng và vẫn thiết lập MyPreciousViewController để hiển thị theo hướng khác với tất cả các tiện ích mở rộng khác như đoạn mã Swift 4 này:

extension UITableViewController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

    if let last = self.navigationController?.childViewControllers.last,
        last != self {
            return last.supportedInterfaceOrientations
    } else {
        return [.portrait]
    }
    }
}

extension MyPreciousViewController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

    return [.portrait,.landscape]
    }
}


extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        return [.portrait]
    }
}


extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        return [.portrait]
    }
}

0

Tôi đã giải quyết cùng một loại vấn đề.

Nếu bạn đang sử dụng UINavigationControllerđể đẩy bộ điều khiển chế độ xem, bạn phải đặt các phương pháp bên dưới.

extension UINavigationController{

    override open var shouldAutorotate: Bool {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return true
        }
        return false
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight

    }
    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {

        if topViewController != nil && (topViewController?.isKind(of: LogInViewController.self))!
        {
            return .portrait
        }
        return .landscapeRight
    }
}

Tại nơi LoginViewControllersử dụng mà UIViewControllerbạn muốn hiển thị. Trong trường hợp của tôi, tôi muốn hiển thị LoginViewControllerPortraitchế độ khác ViewControllerslandscapechế độ.


-1

Vui lòng sử dụng phương pháp sau để giải quyết vấn đề này

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

Chỉ trả lại định hướng bạn muốn !!!


3
Tôi đã làm điều đó, như tôi đã viết. Điều này giúp bộ điều khiển chế độ xem của tôi không xoay, nhưng nó không buộc nó trở lại hướng được hỗ trợ duy nhất khi tôi quay lại nó.
Harald Bögeholz

Điều này không hiệu quả với tôi. Ngay cả khi đã đưa cái này vào bộ điều khiển chế độ xem của tôi, chế độ xem vẫn xoay. Đưa cái gì?
shim

tại sao lại downvote cho maxfiresolutions? Nó hoạt động với tôi và cùng một phương pháp được đưa ra bởi @Flo đang có nhiều lượt ủng hộ.
ViruMax
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.