iphone - para - ¿Puedo acceder a ViewController específico?
como bloquear apps en iphone con huella (14)
Estoy usando una aplicación basada en navegación. Presiono First ViewController a Second ViewController y desde Second ViewController a Third ViewController. Ahora quiero pasar de Third ViewController a First ViewController. Estoy realizando esta tarea usando el siguiente código pero mi aplicación se colgó.
Por favor, cualquier cuerpo me da algunas pautas apropiadas. No puedo usar pop para rootViewController porque es diferente viewController. Gracias por adelantado...
En Third ViewControler escribí esto:
FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
Actualizado para Swift 3:
se usa debajo del código simple, para pop a un controlador de vista específico;
for vc in self.navigationController!.viewControllers as Array {
if vc.isKind(of: YourViewControllerName) {
self.navigationController!.popToViewController(vc, animated: true)
break
}
}
A menudo es más importante hacer eso desde la parte superior de la pila, entonces:
- (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;
}
}
}
y tú llamas eso
popToLast:[SomeViewController class];
Al escribir la primera línea obtienes los índices de todos los controladores de vista y desde la segunda línea llegarás hasta tu destino.
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
Creo que .filter({...}).first
es un poco más lento que .first(where: {...})
. También esto podría escribirse con mayor precisión para abordar solo 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)
}
}
}
Después de mucho esfuerzo, alguien ha creado una rápida extensión de regreso a un controlador de vista particular en 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
}
}
}
}
Método de llamada:
self.navigationController?.backToViewController(viewController: YourViewController.self)
Implementado y probado en Swift 3.0
A continuación se muestra un método que puede ser útil para navegar a cualquier controlador de vista específico:
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;
}
}
}
Uso:
self.poptoSpecificVC(viewController: createIntervalVC.self)
Manera rápida:
let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
navigationController!.popToViewController(dashboardVC, animated: true)
Ponga la función en UIViewController
1. comprueba si existe UIViewController
específico en UINavigationController
luego popToViewController
o 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)
}
Utilizar
self.navigate(ViewController.self, pushVC: self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController)
Rápida y segura versión de Swift 3 :
if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
navigationController.popToViewController(vc, animated: true)
}
Su código crea una nueva instancia de una vista que nunca se ha insertado en la pila, y luego intenta regresar a ese controlador.
Si regresa al controlador de vista raíz, puede usar popToRootViewControllerAnimated:
Si está recuperando una distancia conocida, puede llamar a popViewControllerAnimated:
más de una vez. En su ejemplo, eso sería 2 controladores así que a las llamadas. Usted podría hacer lo mismo mirando en viewControllers
para el controlador 2 desde el final y apareciendo en él.
Las sugerencias anteriores son soluciones rápidas. Un escenario de mejores prácticas sería pasar el controlador al que desea regresar junto con cada controlador sucesivo que presione. Primero se pasa a segundos, segundos pases que hacen referencia a terceros, terceros a la referencia pasada, que es la primera.
En efecto, está creando un controlador raíz temporal. Podría subclase UINavigationController
y agregar una propiedad popToTemporaryRootViewControllerAnimated:
temporaryRoot
y un método popToTemporaryRootViewControllerAnimated:
que aparecería en su raíz temporal y lo borrará. Cuando primero presiona segundos, también se establece como la raíz temporal para que cada controlador en la pila no tenga que pasar una referencia. Tendría que agregar algunos controles adicionales para no estar seguro de que nunca pasa el temporalRoot sin borrarlo.
Un enfoque más seguro:
- (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;
}
}
}
- (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;
}
}
}
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: LoginVC.self) {
_ = self.navigationController!.popToViewController(controller, animated: true)
break
}
}