Могу ли я попнуть к конкретному ViewController?
-
26-09-2019 - |
Вопрос
Я использую навигационное приложение. Я нажимаю первый ViewController к второму ViewController и от второго ViewController до третьего ViewController. Теперь я хочу попнуть от третьего ViewController к первому ViewController.I выполняю эту задачу, используя код ниже, но мое приложение разбилось.
Пожалуйста, любую тело дайте мне несколько правильных руководящих принципов. Я не могу использовать pop to rootviewcontroller, потому что это другой viewcontroller. Заранее спасибо...
В третьем ViewControler я написал это:
FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
Решение
Начиняя первую строку, вы получаете индексы всех контроллеров просмотра и от второй строки вы достигнете до пункта назначения.
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
Другие советы
Безопасный подход:
- (void)turnBackToAnOldViewController{
for (UIViewController *controller in self.navigationController.viewControllers) {
//Do not forget to import AnOldViewController.h
if ([controller isKindOfClass:[AnOldViewController class]]) {
[self.navigationController popToViewController:controller
animated:YES];
return;
}
}
}
Swifty Way:
let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
navigationController!.popToViewController(dashboardVC, animated: true)
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
Часто важнее сделать это с вершины стека, поэтому:
- (void)popToLast:(Class)aClass
{
for (int i=self.navigationController.viewControllers.count-1; i>=0; i--)
{
UIViewController *vc = self.navigationController.viewControllers[i];
if ([vc isKindOfClass:aClass])
{
[self.navigationController popToViewController:vc animated:YES];
break;
}
}
}
и вы называете это
popToLast:[SomeViewController class];
- (void) RetunToSpecificViewController{
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[AnOldViewController class]])
{
//Do not forget to import AnOldViewController.h
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}
}
Быстро и безопасно Swift 3 версия:
if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
navigationController.popToViewController(vc, animated: true)
}
Ваш код создает новый экземпляр мнения, который никогда не был нажат на стек, затем пытается выпрыснуть к этому контроллеру.
Если вы вернемся к контроллеру корневого просмотра, вы можете использовать popToRootViewControllerAnimated:
Если вы появляетесь назад известное расстояние, которое вы можете позвонить popViewControllerAnimated:
больше чем единожды. В вашем примере это было бы 2 контроллера так, чтобы звонить. Вы могли бы сделать то же самое, глядя в viewControllers
Для контроллера 2 от конца и выпрыгнуть к нему.
Вышеуказанные предложения являются быстрыми исправлениями. Одним из лучших практик сценарий будет проходить контроллер, который вы хотите вернуться к каждому последующему контроллеру, который вы нажимаете. Сначала проходит до второго, вторая проходит, что ссылка на третью, третий попс к прохожденной ссылке, которая сначала.
По сути, вы создаете временный контроллер корневого контроллера. Вы можете подкласс UINavigationController
и добавить А. temporaryRoot
собственность и а popToTemporaryRootViewControllerAnimated:
Метод, который выскакивает вашему временному корню и очистить его. Когда сначала толкает секунды, он также установит себя в качестве временного корня, чтобы каждый контроллер в стеке не должен проходить ссылку вокруг. Вам придется добавить некоторые дополнительные чеки, чтобы не уверены, что вы никогда не появляетесь мимо временныхroot, не устраняя его.
После многих усилий кто-то создал Swift расширение обратно на определенный контроллер представления в SWIFT 3.0.
extension UINavigationController {
func backToViewController(viewController: Swift.AnyClass) {
for element in viewControllers as Array {
if element.isKind(of: viewController) {
self.popToViewController(element, animated: true)
break
}
}
}
}
Способ вызова:
self.navigationController?.backToViewController(viewController: YourViewController.self)
Реализован и проверен в Swift 3.0
Ниже приведен способ, который может полезен для навигации на любой конкретный контроллер представления:
func poptoSpecificVC(viewController : Swift.AnyClass){
let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for aViewController in viewControllers {
if aViewController.isKind(of: viewController) {
self.navigationController!.popToViewController(aViewController, animated: true)
break;
}
}
}
Применение :
self.poptoSpecificVC(viewController: createIntervalVC.self)
я думаю что .filter({...}).first
немного медленнее, чем .first(where: {...})
. Отказ Также это может быть написано более именно для решения только UIViewControllers.
extension UINavigationController {
func popToController<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
}
}
func popToControllerOrToRootControllerIfNotInTheStack<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
} else {
popToRootViewController(animated: animated)
}
}
}
Обновлено для Swift 3:
используется ниже простого кода для POP к определенному контроллеру представления;
for vc in self.navigationController!.viewControllers as Array {
if vc.isKind(of: YourViewControllerName) {
self.navigationController!.popToViewController(vc, animated: true)
break
}
}
Swift 4. версия
if let viewController = navigationController?.viewControllers.first(where: {$0 is YourViewController}) {
navigationController?.popToViewController(viewController, animated: false)
}
Вы можете указать другой фильтр на .viewControllers.first
Согласно вашему потребности, например, давайте скажем, если у вас есть же kind
Представления контроллеров просмотра, проживающих в контроллере навигации, вы можете указать дополнительную проверку, как ниже
if let viewController = navigationController?.viewControllers.first(where: {
if let current = $0 as? YourViewController {
return current.someProperty == "SOME VALUE"
}
return false } ) {
navigationController?.popToViewController(viewController, animated: false)
}
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: LoginVC.self) {
_ = self.navigationController!.popToViewController(controller, animated: true)
break
}
}
Вставьте функцию UIViewController
1. Это проверяет, если конкретно UIViewController
существует внутри UINavigationController
тогда popToViewController
или еще pushViewController
func navigate(_ navVC: AnyClass, pushVC: UIViewController) {
for obj in self.navigationController!.viewControllers {
if obj.isMember(of: navVC) {
self.navigationController!.popToViewController(obj, animated: true)
return
}
}
self.navigationController!.pushViewController(pushVC, animated: true)
}
Использовать
self.navigate(ViewController.self, pushVC: self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController)
У меня есть ответ здесь. Это 100% рабочий код для Swift> 4.x.
Как я могу поп-определенный контроллер представления в SWIFT