ios - unwind - Ejecutar push segue después de un desenrollado
unwind segue programmatically swift 4 (6)
Estoy trabajando en una aplicación de cámara donde las vistas de la cámara se muestran modalmente. Después de que haya terminado con los cultivos. Realizo un segue desenrollar al MainPageViewController
. (Por favor vea la captura de pantalla)
Mi función de desenrollar dentro de MainPageViewController
es la siguiente;
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
self.performSegueWithIdentifier("Categories", sender: self)
}
donde "categorías" es el identificador de MainPageViewController
de MainPageViewController
de MainPageViewController
a CategoriesTableViewController
.
El programa ingresa a la función unwindToMainMenu
pero no realiza el segmento de inserción. ¿Algúna idea de cómo arreglar esto?
Nota: encontré la misma question pero la respuesta sugiere cambiar la estructura del guión gráfico.
Avanzando esta respuesta (solo tuve código Objective-C)
Subclase UIStoryBoardSegue
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegue
/**
This block is called after completion of animations scheduled by @p self.
*/
@property (nonatomic, copy) void(^completion)();
@end
Y llama a este bloque de terminación después de completar las animaciones.
@implementation MyStoryboardSegue
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
Avanzando las dos respuestas anteriores, hay un poco más de detalles sobre la versión de object c aquí (yo también solo tenía el código Objective-C)
Subclase UIStoryboardSegue con UIStoryboardSegueWithCompletion
clase UIStoryboardSegueWithCompletion: UIStoryboardSegue {var complete: (() -> Void)?
override func perform() { super.perform() if let completion = completion { completion() } }
}
UIStoryboardSegueWithCompletion.h
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegueWithCompletion
@property (nonatomic, copy) void(^completion)();
@end
UIStoryboardSegueWithCompletion.m
#import "UIStoryboardSegueWithCompletion.h"
@implementation UIStoryboardSegueWithCompletion
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
- Establezca UIStoryBoardSegueWithCompletion como la clase para su salida segue
nota: la acción para este segmento debe ser unwindToMainMenu para que coincida con la pregunta original [imagen que muestra ui de segue] [1] [imagen que muestra ui de segue 2] [2]
Seleccione salir segue del guión gráfico Agregar clase personalizada
-(IBAction)unwindToMainMenu(UIStoryboardSegue *)segue {
if([segue isKindOfClass:[UIStoryboardSegueWithCompletion class]]){
UIStoryboardSegueWithCompletion *segtemp = segue;// local prevents warning
segtemp.completion = ^{
NSLog(@"segue completion");
[self performSegueWithIdentifier:@"Categories" sender:self];
};
}
}
Tu código ahora se ejecutará después de que el segmento de salida complete su transición
El método IBAction de salida de segmento se realiza antes de que finalice el segmento de desenrollado real. Tuve el mismo problema y lo resolví de esta manera (si no te importa parafrasear tu código). Evita el tiempo extra y las animaciones de confiar en ViewDidAppear.
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
let categoriesTable = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("CategoryTableViewController")
self.navigationController?.viewControllers.append(categoriesTable)
self.navigationController?.showViewController(categoriesTable, sender: self)
}
¡Espero que esto sea útil para cualquier otra persona que se encuentre con esto y solo quiera una transición instantánea!
Quiero proporcionar mi propia solución a este problema por ahora. Cualquier otra respuesta siempre es bienvenida.
Puse una variable booleana y la función MainPageViewController
en MainPageViewController
.
var fromCamera = false
override func viewDidAppear(animated: Bool) {
if fromCamera {
self.performSegueWithIdentifier("categorySelection", sender: self)
self.fromCamera = false
}
}
Establecí fromCamera
en true
antes de realizar el CropViewController
segue de CropViewController
. De esa manera, realizo la pantalla de segue a categoría solo si se realiza un segue de desenrollar de la vista de recorte.
Supongo que performSegue no se está disparando porque el segmento de desenrollado aún no ha finalizado. Lo único en lo que puedo pensar en este momento es retrasar la llamada a performSegue usando dispatch_after
. Sin embargo, esto me parece muy "hacky".
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
dispatch_after(1, dispatch_get_main_queue()) { () -> Void in
self.performSegueWithIdentifier("Categories", sender: self)
}
}
Un poco tarde para la fiesta, pero encontré una manera de hacerlo sin usar banderas de estado
Nota: esto solo funciona con iOS 9+, ya que solo los segmentos personalizados admiten nombres de clase anteriores a iOS9 y no puede declarar un segmento de salida como un segmento personalizado en los guiones gráficos
1. Subclase UIStoryboardSegue con UIStoryboardSegueWithCompletion
class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?
override func perform() {
super.perform()
if let completion = completion {
completion()
}
}
}
2. Establezca UIStoryBoardSegueWithCompletion como la clase para su salida segue
nota: la acción para este segmento debe ser unwindToMainMenu
para que coincida con la pregunta original
3. Actualice su desenlace @IBAction para ejecutar el código en el controlador de finalización
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
if let segue = segue as? UIStoryboardSegueWithCompletion {
segue.completion = {
self.performSegueWithIdentifier("Categories", sender: self)
}
}
}
Tu código ahora se ejecutará después de que el segmento de salida complete su transición