it-swarm.com.ru

Предупреждение: -Представление контроллеров представления на контроллерах отдельного представления не рекомендуется

В моем приложении я использую навигационный контроллер. Позже, в некоторых случаях, я использую presentViewController для показа увеличенного изображения . Также я не использую раскадровку или перо. 

Я получаю эту ошибку только в iOS 7. Он отлично работает в iOS 6 и более ранних версиях:

Представление контроллеров представления на контроллерах отдельного представления является обескураженный

162
Gagan Joshi

Одним из решений этого является, если у вас есть childviewcontroller, так что вы просто представляете viewviewcontroller на его родительском 

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

А для отклонения используйте тот же контроллер dismissview.

[self dismissViewControllerAnimated:YES completion:nil];

Это идеальное решение работает для меня.

8
Gagan Joshi

Чтобы избежать получения предупреждения в Push-навигации, вы можете напрямую использовать:

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

И затем в вашем контроллере модального представления, когда все закончится, вы можете просто позвонить: 

[self dismissViewControllerAnimated:YES completion:nil];

197
cdescours

Причина этого предупреждения в том, что я представлял контроллер представления поверх небольшого представления, которое не является полноразмерным представлением. Ниже приведено изображение моего проекта. где при нажатии на четыре варианта выше. Пользователь переходит к другому представлению childviewcontroller (работает как tabViewcontroller). Но childviewcontroller содержит представление небольшого размера. Так что, если мы представляем представление childviewcontroller, оно выдает это предупреждение. 

master detail view

И чтобы избежать этого, вы можете представить представление о родителе childviewcontroller

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

Подождите viewDidAppear():

Эта ошибка также может возникать, если вы пытаетесь представить контроллер представления до того, как представление действительно появилось, например, представление представления в viewWillAppear() или более ранней версии . Попробуйте представить другое представление после viewDidAppear() или внутри него.

45
Azaxis

В моем случае я добавил представление sampleViewController как подпредставление, а затем попытался представить всплывающее окно из представления sampleViewController (здесь self вместо экземпляра UIViewController):

[self.view addSubview:sampleViewController.view];

Правильный путь должен быть ниже:

// 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];

Кстати, это также работает для случая, который представляет поповер из ячейки табличного представления, вам просто нужно убедиться, что контроллер табличного представления также был добавлен в качестве дочернего контроллера представления.

18
Kjuly

Я думаю, что проблема в том, что у вас нет правильной иерархии контроллеров представления. Установите rootviewcontroller приложения и затем отображайте новые представления, выдвигая или представляя на них новые контроллеры представлений. Пусть каждый контроллер представления управляет своими представлениями. Только контроллеры представления контейнера, такие как tabbarviewcontroller, должны когда-либо добавлять другие представления контроллеров представления к своим собственным представлениям. Прочтите руководство по программированию контроллеров представления, чтобы узнать больше о том, как правильно использовать контроллеры представления. https://developer.Apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/

16
Daniel Ytterbrink

У меня почти такая же проблема. Причина была в том, что я пытался представить «некоторый» контроллер на другом, и после завершения анимации я устанавливал представленный контроллер как root. После этой операции все дальнейшие представления контроллеров приводят меня к предупреждению: « Представление контроллеров представления на контроллерах отдельного представления не рекомендуется ». И я решаю это предупреждение просто настройкой «какого-то» контроллера как root без какой-либо презентации в начале.

Удалены:

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

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Просто сделайте как root без каких-либо презентаций:

 [[self window] setRootViewController:controller];
9
averem

Swift 3

Для тех, кто спотыкается об этом, вот ответ Swift.

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

Используйте [self.navigationController presentViewController:xxx animated:YES completion:nil] в iOS 8.

6
Tao Fang

Попробуйте этот код

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

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

Да, я также столкнулся с тем же предупреждающим сообщением при отображении контроллера оповещений, который был в другом представлении. Позже я избежал этого, представив контроллер оповещений из родительского контроллера представления, как показано ниже:

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

вам нужно добавить контроллер представления, который будет представлять новый контроллер как дочерний элемент родительского контроллера представления.

Допустим, у вас есть yourMainViewController, затем вы добавляете новый контроллер с именем controllerA и затем хотите представить новый контроллер с именем controllerB от controllerA

вы должны написать что-то вроде этого:

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

и в controllerA вы можете представить новый контроллер без предупреждений

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

Попробуйте представить на TabBarController, если это приложение на основе TabBarController

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

Причиной может быть self, потомок TabBarController, и вы пытаетесь представить его из ChildViewController.

2
Warif Akhand Rishi

Убедитесь, что у вас есть контроллер корневого представления для начала. Вы можете установить его в didFinishLaunchingWithOptions.

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

Много причин для этого предупреждения. Мой, потому что у меня есть переход, связанный с ViewController к другому, который будет представлен модально. Но ViewController, который я представляю, динамически генерируется PageViewController. Вот почему он отделен в раскадровке. Мое приложение не будет зависать из-за этого; но я хотел бы заставить замолчать предупреждение.

1
Lee Probert

В Swift 4.1 и Xcode 9.4.1

Решение 

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

Если напишите так, я получаю ту же ошибку

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) 

Я получаю ту же ошибку

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

Полное решение 

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)
})
0
iOS

Это зависит от того, хотите ли вы показать свое предупреждение или что-то подобное в любом месте вида UIViewController.

Вы можете использовать этот пример кода:

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];
0
Fabio