ios - tirar - contenedores de reciclaje por colores
Desde dentro de un controlador de vista en una vista de contenedor, ¿cómo se accede al controlador de vista que contiene el contenedor? (7)
1) en VC2 expone una propiedad para pasar en una referencia a VC1
//VC2.h
#import "VC1.h"
@interface VC2 : NSObject
@property (strong, nonatomic) VC1 *parent;
@end
2) en VC1, pase a la propiedad expuesta en VC2 en su método prepareForSegue después de configurar el identificador de segue en "ToVC2". A continuación, pase la referencia así:
//VC1.m
@implementation VC1
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"ToVC2"]) {
VC2 *vc2 = segue.destinationViewController;
vc2.parent = self;
}
}
Esto es difícil de decir pero tengo un controlador de vista (vc1) que contiene una vista de contenedor (estoy usando guiones gráficos). Dentro de esa vista de contenedor hay un controlador de navegación y un controlador de vista raíz (vc2).
Desde vc2 ¿cómo puedo obtener acceso a vc1?
O bien, ¿cómo paso vc1 a vc2? (teniendo en cuenta que estoy usando guiones gráficos).
Gracias Bonnie por decirme qué hacer. De hecho, la preparación para el método segue es el camino a seguir.
Solo estoy aclarando el código y los pasos aquí.
Entonces, primero, nombre el segue (enlace) en el guión gráfico que conecta la vista del contenedor con su primer controlador de vista. Llamé a la mía "toContainer".
Luego, en el controlador de vista que contiene la vista de contenedor, agregue este método
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: @"toContainer"]) {
UINavigationController *navViewController = (UINavigationController *) [segue destinationViewController];
UIViewController *vc2 = [navViewController viewControllers][0];
}
}
Entonces vc2 era el controlador al que quería hacer referencia.
Esto funcionó para mí, su método sería ligeramente diferente dentro de prepareForSegue si su primer controlador de vista no fuera un controlador de navegación.
Para acceder al controlador de vista principal desde su controlador de vista secundaria, debe anular didMoveToParentViewController :
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
//Use parent
}
En Xcode Command + haga clic sobre este método para obtener más información:
Estos dos métodos son públicos para que las subclases de contenedor llamen cuando se realiza la transición entre los controladores secundarios. Si se anulan, las anulaciones deben garantizar llamar al súper. El argumento principal en ambos métodos es nulo cuando un hijo se elimina de su padre; de lo contrario, es igual al nuevo controlador de vista principal.
addChildViewController: llamará a [child willMoveToParentViewController: self] antes de agregar el elemento secundario. Sin embargo, no llamará a didMoveToParentViewController :. Se espera que una subclase de controlador de vista de contenedor realice esta llamada después de que se haya completado una transición al nuevo elemento secundario o, en el caso de ninguna transición, inmediatamente después de la llamada a addChildViewController :. De forma similar, removeFromViewController: no llama a [self willMoveToParentViewController: nil] antes de eliminar el elemento secundario. Esta es también la responsabilidad de la subclase contenedor. Las subclases de contenedor típicamente definirán un método que hace la transición a un nuevo hijo llamando primero a addChildViewController :, luego, ejecutando una transición que agregará la vista del nuevo hijo a la jerarquía de vista de su elemento primario, y finalmente llamará a didMoveToParentViewController :. De manera similar, las subclases típicamente definirán un método que elimine a un niño de manera inversa llamando primero a [child willMoveToParentViewController: nil].
Puede usar la delegación usando el mismo método que usó Bonnie. Así es como lo haces:
En su containerViews ViewController:
class ContainerViewViewController: UIViewController {
//viewDidLoad and other methods
var delegate: ContainerViewControllerProtocol?
@IBAction func someButtonTouched(sender: AnyObject) {
self.delegate?.someDelegateMethod() //call this anywhere
}
}
protocol ContainerViewControllerProtocol {
func someDelegateMethod()
}
En tu ViewController primario:
class ParentViewController: UIViewController, ContainerViewControllerProtocol {
//viewDidLoad and other methods
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "filterEmbedSegue" {
let containerViewViewController = segue.destinationViewController as ContainerViewViewController
containerViewViewController.delegate = self
}
}
func someDelegateMethod() {
//do your thing
}
}
Swift: una alternativa es crear una referencia en el UIViewController padre (vc1) a child / subview UIViewController (vc2) y en vc2 a vc1. Asigne las referencias en el ejemplo principal (vc1) viewDidLoad () a continuación.
Padre UIViewController vc1:
class vc1: UIViewController {
@IBOutlet weak var parentLabel: UILabel!
var childVc2: vc2?;
overide func viewDidLoad() {
super.viewDidLoad();
// Use childViewControllers[0] without type/class verification only
// when adding a single child UIViewController
childVc2 = self.childViewControllers[0] as? vc2;
childVc2?.parentVc1 = self
}
}
Niño UIViewController vc2:
class vc2: UIViewCortoller {
var parentVc1: vc1?;
// At this point child and parent UIViewControllers are loaded and
// child views can be accessed
override func viewWillAppear(_ animated: Bool) {
parentVc1?.parentLabel.text = "Parent label can be edited from child";
}
}
En el Storyboard, recuerde configurar en Identity Inspector la clase primaria UIViewContoller para vc1 y la clase secundaria UIViewContoller para vc2. Ctrl + arrastre desde Vista de contenedor en vc1 UIViewController a vc2 UIViewController y seleccione Incrustar.
Use la propiedad parentViewController
como self.parentViewController
Puede usar el método prepareForSegue
en Vc1 ya que se produce una transición de inserción cuando ContainerViewController se convierte en un elemento secundario. puede pasar self como un obj o almacenar una referencia al niño para su uso posterior.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: @"embedseg"]) {
UINavigationController * navViewController = (UINavigationController *) [segue destinationViewController];
Vc2 *detail=[navViewController viewControllers][0];
Vc2.parentController=self;
}
}
Editar: corrección de código menor