Cảnh báo: -Trình bày các bộ điều khiển xem trên các bộ điều khiển xem tách rời không được khuyến khích


180

Trong ứng dụng của tôi, tôi đang sử dụng bộ điều khiển điều hướng. Sau này trong một số chế độ xem tôi đang sử dụng presentViewControllerđể hiển thị hình ảnh được phóng to. Ngoài ra tôi không sử dụng Storyboard hay ngòi.

Tôi chỉ gặp lỗi này trong iOS 7. Nó hoạt động tốt trong iOS 6 trở về trước:

Trình bày các bộ điều khiển xem trên các bộ điều khiển xem tách rời không được khuyến khích


Tôi chưa tìm ra. Nhưng trong ứng dụng của tôi, tôi không gán bất kỳ trình điều khiển khung nhìn nào cho window.rootviewcontroll. tôi đang thêm chế độ xem vào cửa sổ. Có thể đó là lý do cho tôi. nhưng không chắc chắn ...
Gagan Joshi

@GaganJoshi Lý do bạn đề cập ở trên có thể không phải là nguyên nhân. Ngay cả tôi cũng đang đối mặt với cùng một vấn đề. Và trong dự án của chúng tôi, tôi đang gán một bộ điều khiển xem cho window.rootviewcontroll.
Rajesh

1
Tôi nghĩ rằng các ý kiến ​​khác liên quan chính xác điều này với một cái gì đó về rootViewControll và kết nối cửa sổ. Tôi đã không hoàn toàn hiểu được điều đó, nhưng tôi đã có thể giải quyết vấn đề bằng cách trình bày bộ điều khiển trực tiếp trên rootViewContaptor thay vì trên bộ điều khiển điều hướng hoặc một trong những đứa con của nó.
Vùng biển phong phú

Câu trả lời:


207

Để tránh nhận được cảnh báo trong điều hướng đẩy, bạn có thể trực tiếp sử dụng:

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

Và sau đó trong trình điều khiển chế độ xem phương thức của bạn, khi mọi thứ kết thúc, bạn chỉ cần gọi:

[self dismissViewControllerAnimated:YES completion:nil];


Tôi đang trình bày trình chọn hình ảnh với mã dòng này "[self.view.window.rootViewControll PresentViewCont điều khiển: viewContoder hoạt hình: hoàn thành CÓ: nil];" Nhưng không thể loại bỏ chế độ xem poicker với dòng này "[self notifyViewControllAnimated: YES hoàn thành: nil];" Bất kỳ tùy chọn thay thế nào cho trình điều khiển loại bỏ
kb920

@keyurbhalodiya Bạn cần gọi phương thức notifyViewContoder từ modalView để làm cho nó hoạt động. Vì vậy, nếu bạn đã hiển thị một khung nhìn có tên viewB từ một viewA với [viewA.window.rootViewControll PresentViewContoder: viewB], trong viewB, bạn cần thêm một nút, ví dụ, liên kết với một hành động tùy chỉnh gọi [self notifyViewControllAnimated]. Có rõ ràng hơn không?
cdescours

11
Không trình bày trình điều khiển trong iOS 8.
Rajesh Maurya

1
cho iOS 8: [self.view.window.rootViewControll.navlationControll
Fede Cugliandolo

31
sử dụng self.navigationControllerđã làm điều đó cho tôi.
Brandon Zacharie 17/03/2015

62

Lý do của cảnh báo này là tôi đã trình bày một bộ điều khiển chế độ xem qua một chế độ xem nhỏ không phải là chế độ xem kích thước đầy đủ. Đưa ra dưới đây là hình ảnh của dự án của tôi. trong đó nhấp vào bốn tùy chọn ở trên. Người dùng điều hướng đến chế độ xem khác nhau của trình điều khiển con. (Nó hoạt động như tabViewcontroll). Nhưng bộ điều khiển con có chứa khung nhìn kích thước nhỏ. Vì vậy, nếu chúng tôi trình bày một quan điểm từ bộ điều khiển con, nó đưa ra cảnh báo này.

xem chi tiết tổng thể

Và để tránh điều này, bạn có thể trình bày quan điểm về cha mẹ của trình điều khiển con

  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

1
[self.view.window.rootViewControll.navlationControll PushViewCont điều khiển: YOU_VIEW_CONTROLER hoạt hình: CÓ];
Fede Cugliandolo

1
"đã trình bày một bộ điều khiển chế độ xem qua một chế độ xem nhỏ không phải là chế độ xem kích thước đầy đủ." ... CHÍNH XÁC. Công việc tốt đẹp.
Fattie

61

Đợi viewDidAppear():

Lỗi này cũng có thể phát sinh nếu bạn đang cố gắng trình bày bộ điều khiển xem trước khi chế độ xem thực sự xuất hiện, ví dụ như trình bày chế độ xem trong viewWillAppear()hoặc trước đó. Cố gắng trình bày một quan điểm khác sau viewDidAppear()hoặc bên trong nó.


9
Nói cách khác, đừng trình bày bất kỳ bộ điều khiển xem nào viewDidLoad(), mọi người! Tôi đã mắc lỗi này rất nhiều lần ...
T Trống

Cảm ơn điều này đã giúp. Tôi đã có mã trong viewDidLoad khi nó cố gắng hiển thị một hộp thoại ở cuối.
ArdenDev

Tôi gặp lỗi này khi chạy kiểm tra đơn vị / tích hợp trong đó tôi không kiểm tra hoạt ảnh.
mixtly87

21

Trong trường hợp của tôi, sampleViewControllerchế độ xem của tôi đã được thêm dưới dạng một khung nhìn phụ, sau đó cố gắng trình bày một cửa sổ bật lên từ chế độ xem sampleViewController(ở đây selfthay vì một UIViewControllerví dụ):

[self.view addSubview:sampleViewController.view];

Cách đúng nên dưới đây:

// make sure the vc has been added as a child view controller as well
[self addChildViewController:sampleViewController];
[self.view addSubview:sampleViewController.view];
[sampleViewController didMoveToParentViewController:self];

Btw, điều này cũng hoạt động đối với trường hợp trình bày một popover tạo thành một ô xem bảng, bạn chỉ cần đảm bảo rằng bộ điều khiển xem bảng cũng đã được thêm làm trình điều khiển xem con.


Ngoài ra, hãy gọi didMoveToParentViewControll. Yêu cầu kiểm tra Thêm và xóa ChildViewControll: gist.github.com/tomohisa/2897676
Jakehao

@jianzong tôi nhớ không cần phải làm bước cuối cùng. Bất cứ cách nào, hãy để tôi thêm nó, thx cho gợi ý. :)
Kjuly

Có nó sẽ hoạt động mà không cần bước cuối cùng. Tôi nghĩ mục đích của nó là thông báo cho ParentViewControll để nó sẽ gọi một số phương thức để làm một cái gì đó. :)
Jakehao

2
nó hoạt động với tôi, tôi đang sử dụng chế độ xem một bộ điều khiển trong một bộ điều khiển khác - (Chế độ xem Container theo chương trình), tôi đã không thêm [self addChildViewController:sampleViewController];, bây giờ tôi đã thêm cái này, cảm ơn bạn
anjnkmr

16

Tôi nghĩ rằng vấn đề là bạn không có hệ thống phân cấp bộ điều khiển xem đúng. Đặt bộ điều khiển gốc của ứng dụng và sau đó hiển thị các chế độ xem mới bằng cách đẩy hoặc hiển thị các bộ điều khiển chế độ xem mới trên chúng. Hãy để mỗi bộ điều khiển xem quản lý quan điểm của họ. Chỉ các bộ điều khiển chế độ xem bộ chứa, như bộ điều khiển tabbarview, mới nên thêm các chế độ xem bộ điều khiển xem khác vào chế độ xem của riêng chúng. Đọc hướng dẫn lập trình bộ điều khiển xem để tìm hiểu thêm về cách sử dụng bộ điều khiển xem đúng cách. https://developer.apple.com/lvern/content/featuredarticles/ViewControllPGforiPhoneOS/


14

Swift 3

Đối với bất cứ ai vấp ngã về điều này, đây là câu trả lời nhanh chóng.

self.parent?.present(viewController, animated: true, completion: nil)

9

Tôi có vấn đề gần như tương tự. Lý do là tôi đã cố gắng trình bày bộ điều khiển "một số" trên một bộ điều khiển khác và sau khi hoạt ảnh hoàn thành, tôi đã thiết lập trình điều khiển được trình bày dưới dạng root. Sau thao tác này, tất cả các bộ điều khiển tiếp theo trình bày đưa tôi đến cảnh báo: " Trình bày các bộ điều khiển xem trên các bộ điều khiển xem tách rời là không được khuyến khích ". Và tôi giải quyết cảnh báo này chỉ cài đặt bộ điều khiển "một số" là root mà không có bất kỳ sự trình bày nào khi bắt đầu.

Đã xóa:

[[self rootController] presentViewController:controller animated:YES completion:^{

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Chỉ cần làm root mà không cần trình bày:

 [[self window] setRootViewController:controller];

1
Đây chính xác là vấn đề của tôi. Đã cố gắng trình bày nó với một UIModalTransitionStyleCrossDissolve và sau đó làm cho nó rootViewControll. Sau đó, tất cả các bài thuyết trình khác đều thất bại với thông điệp cảnh báo đã cho. Chỉ cần thiết lập nó là rootViewcontroll mà không có hình động đã thực hiện thủ thuật. Cảm ơn!
Bernardo Oliveira

7

Một trong những giải pháp cho vấn đề này là nếu bạn có trình điều khiển con, vì vậy bạn chỉ cần trình điều khiển trình chiếu trên cha mẹ của nó bằng cách cho

[self.parentViewController presentViewController:viewController animated:YES completion:nil];

Và để loại bỏ sử dụng bộ điều khiển bỏ qua tương tự.

[self dismissViewControllerAnimated:YES completion:nil];

Đây là giải pháp hoàn hảo làm việc cho tôi.


7

Sử dụng [self.navigationController presentViewController:xxx animated:YES completion:nil]trong iOS 8.


5

Hãy thử mã này

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];

[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

4

Hãy thử trình bày TabBarControllernếu nó là một TabBarControllerứng dụng dựa trên.

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

Lý do có thể selflà con của TabBarControllervà bạn đang cố gắng trình bày từ a ChildViewController.


4

Có, tôi cũng phải đối mặt với thông báo cảnh báo tương tự trong khi hiển thị Bộ điều khiển cảnh báo ở chế độ xem khác. Sau này tôi đã tránh điều này bằng cách trình bày bộ điều khiển cảnh báo từ bộ điều khiển xem cha mẹ như dưới đây:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

3

bạn cần thêm bộ điều khiển khung nhìn sẽ trình bày bộ điều khiển mới với tư cách là con của bộ điều khiển khung nhìn cha.

Giả sử bạn có yourMainViewContoder, sau đó bạn thêm một bộ điều khiển mới có tên là controlA, và sau đó bạn muốn trình bày một bộ điều khiển mới có tên là controlB từ bộ điều khiểnA

bạn phải viết một cái gì đó như thế này:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view]; 

và trong bộ điều khiểnA bạn có thể trình bày bộ điều khiển mới mà không cần cảnh báo

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

3

Trong Swift 4.1 và Xcode 9.4.1

Giải pháp là

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

Nếu viết như thế này thì tôi cũng bị lỗi tương tự

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
    })
alert.addAction(defaultAction)

present(alert, animated: true, completion: nil) 

Tôi đang bị lỗi tương tự

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

Giải pháp hoàn chỉnh là

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
     })
alert.addAction(defaultAction)
//Made Changes here    
DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

Chạy nó thông qua DispatchQueue như thế này làm việc cho tôi. Tôi đang thực hiện một Trình diễn cho trình điều khiển chế độ xem theo chế độ, được gọi từ viewDidLoad trên trình điều khiển chế độ xem đầu tiên của tôi (màn hình giới thiệu lần đầu tiên để định hướng người dùng mới). Nó đã được tải tốt, nhưng tạo ra cảnh báo. Kết thúc cuộc gọi PerformanceSegue trong cuộc gọi không đồng bộ của DispatchQueue sẽ loại bỏ cảnh báo. Cảm ơn!
Cấp Neufeld

1

Hãy chắc chắn rằng bạn có một bộ điều khiển xem gốc để bắt đầu. Bạn có thể đặt nó trong didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

1

Rất nhiều lý do cho cảnh báo này. Của tôi là bởi vì tôi có một segue được kết nối từ ViewContoder đến một cái khác sẽ được trình bày theo phương thức. Nhưng, ViewContoder mà tôi đang trình bày đang được tạo ra một cách linh hoạt bởi PageViewControll. Đó là lý do tại sao nó được tách ra trong Storyboard. Ứng dụng của tôi sẽ không bị sập vì nó; nhưng tôi muốn im lặng cảnh báo.


1

Tôi đã tiếp cận chủ đề này nơi tôi có Thanh điều hướng tùy chỉnh và tôi đang gọi AlertViewControll thông qua nó.

Tôi đã phải thêm nó khi còn nhỏ vào bộ điều khiển xem chính của mình. Sau đó tôi có thể gọi trình bày nó mà không có bất kỳ cảnh báo.

Bạn nên thêm bạn Zoomed Image View Controllerlà con của ViewContoder chính.

(ví dụ)

[self addChildViewController:ZoomedImageViewController];

Sau đó, bạn có thể gọi ZoomedImageViewControll của bạn

[self presentViewController:ZoomedImageViewController];

1

Nhiều câu trả lời là đúng.

  • Kiểm tra PresentingViewControll của bạn có cha mẹ hay không.
  • Nếu không, thêm nó vào một nơi nào đó cần được thêm vào
  • mặt khác, hãy kiểm tra xem cha mẹ của nó có cha mẹ có kiểm soát đệ quy cho đến khi mọi viewContaptor có cha

Vấn đề này đã xảy ra với tôi khi đồng nghiệp của tôi thêm AViewContoder vào BViewControll. Bằng cách nào đó, anh ta chỉ cần thêm chế độ xem của AViewContoder vào chế độ xem của BViewContoder.

Đã sửa lỗi bằng cách thêm bViewControll.addChild (aViewControll)


1
Cảm ơn bạn! thêm addChild trong khối hoàn thành Hero. Shared.transition của tôi đã giải quyết hoàn toàn vấn đề của tôi.
Landnbloc

0

Nó phụ thuộc nếu bạn muốn hiển thị cảnh báo của mình hoặc một cái gì đó tương tự ở bất kỳ nơi nào thuộc loại UIViewControll.

Bạn có thể sử dụng ví dụ mã này:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil];

[alert addAction:cancelAction];


[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];

Với mã của bạn, nó không hoạt động và cung cấp nhật ký nàyAttempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!
Naveed Abbas
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.