icon - Cambie el contenido de la vista del contenedor con pestañas en iOS
status bar ios (5)
Estoy tratando de hacer un formulario que abarca tres pestañas. Puedes ver en la captura de pantalla debajo de las pestañas. Cuando el usuario toca una pestaña, la Vista del contenedor debería actualizarse y mostrar el controlador de vista particular que tengo.
Pestaña 1 = Controlador de vista 1
Pestaña 2 = Controlador de vista 2
Pestaña 3 = Controlador de vista 3
El controlador de vista que se muestra arriba tiene la clase PPAddEntryViewController.m. Creé una salida para la vista de Contenedor dentro de esta clase y ahora tengo una propiedad de Vista de Contenedor:
@property (weak, nonatomic) IBOutlet UIView *container;
También tengo preparadas mis IBActions para mis pestañas:
- (IBAction)tab1:(id)sender {
//...
}
- (IBAction)tab2:(id)sender {
//...
}
- (IBAction)tab3:(id)sender {
//...
}
¿Cómo configuro el contenedor en esas IBActions para cambiar el controlador de vista que tiene la vista de contenedor?
Entre otras cosas, esto es lo que he intentado:
UIViewController *viewController1 = [self.storyboard instantiateViewControllerWithIdentifier:@"vc1"];
_container.view = viewController1;
... pero no funciona. Gracias por adelantado.
Conmutación usando Storyboard, diseño automático o no, un botón de algún tipo y una serie de controladores de vista infantil
Desea agregar la vista de contenedor a su vista y cuando los botones que "cambian" a los controladores de vista secundarios se presionan, se activan el segmento apropiado y se realizan los trabajos de configuración correctos.
En el Guión gráfico solo puede conectar un Segmento Incrustado a la Vista de Contenedor. Así que creas un controlador de manejo intermedio. Cree el segmento de inserción y asígnele un identificador, por ejemplo, EmbededSegueIdentifier.
En el controlador de la vista principal, conecte el botón o lo que desee y mantenga la referencia del controlador de la vista secundaria en el segmento de preparación. Tan pronto como el controlador de vista principal se cargue, se activará el segmento.
El controlador de vista de padres
@property (weak, nonatomic) MyContainerViewController *myContainerViewController;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"EmbeddedSegueIdentifier"]) {
self.myContainerViewController = segue.destinationViewController;
}
}
Debería ser bastante fácil para usted delegar a su controlador de contenedor el botón presiona.
El controlador de contenedores
Este siguiente bit de código fue tomado en parte de un par de fuentes, pero el cambio clave es que el diseño automático se utiliza en lugar de marcos explícitos. No hay nada que le impida simplemente cambiar las líneas [self addConstraintsForViewController:]
para viewController.view.frame = self.view.bounds
. En el Guión gráfico, este controlador de vista de contenedor no hace nada más que seguir a los controladores de vista secundarios de destino.
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%s", __PRETTY_FUNCTION__);
[self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationViewController = segue.destinationViewController;
if ([self.childViewControllers count] > 0) {
UIViewController *fromViewController = [self.childViewControllers firstObject];
[self swapFromViewController:fromViewController toViewController:destinationViewController];
} else {
[self initializeChildViewController:destinationViewController];
}
}
- (void)initializeChildViewController:(UIViewController *)viewController
{
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[self addConstraintsForViewController:viewController];
[viewController didMoveToParentViewController:self];
}
- (void)swapFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController
{
[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];
[self transitionFromViewController:fromViewController toViewController:toViewController duration:0.2f options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:^(BOOL finished) {
[self addConstraintsForViewController:toViewController];
[fromViewController removeFromParentViewController];
[toViewController didMoveToParentViewController:self];
}];
}
- (void)addConstraintsForViewController:(UIViewController *)viewController
{
UIView *containerView = self.view;
UIView *childView = viewController.view;
[childView setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:childView];
NSDictionary *views = NSDictionaryOfVariableBindings(childView);
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[childView]|"
options:0
metrics:nil
views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[childView]|"
options:0
metrics:nil
views:views]];
}
#pragma mark - Setters
- (void)setSelectedControl:(ViewControllerSelectionType)selectedControl
{
_selectedControl = selectedControl;
switch (self.selectedControl) {
case kFirstViewController:
[self performSegueWithIdentifier:@"FirstViewControllerSegue" sender:nil];
break;
case kSecondViewController:
[self performSegueWithIdentifier:@"SecondViewControllerSegue" sender:nil];
break;
default:
break;
}
}
Los Segues personalizados
Lo último que necesita es un segmento personalizado que no hace nada, yendo a cada destino con el identificador de segmento apropiado que se llama desde el controlador de la vista del contenedor. Si no se pone en un método de ejecución vacío, la aplicación se bloqueará. Normalmente se podría hacer una animación de transición personalizada aquí.
@implementation SHCDummySegue
@interface SHCDummySegue : UIStoryboardSegue
@end
- (void)perform
{
// This space intentionally left blank
}
@end
Conseguí que esto funcionara usando un UITabBarController. Para usar pestañas personalizadas, tuve que subclasificar el TabBarController y agregar los botones al controlador en el código. Luego escucho los eventos de tap en los botones y configuro el selectedIndex
para cada pestaña.
Fue bastante sencillo, pero es un montón de basura en mi Guión gráfico para algo tan simple como 3 pestañas.
Recientemente encontré el código de ejemplo perfecto para lo que estaba tratando de hacer. Incluye la implementación de Storyboard y todos los segmentos y códigos relevantes. Fue realmente útil.
tener una variable miembro para mantener el viewController:
UIViewController *selectedViewController;
ahora en las acciones de IBA, cambia eso y la vista. p.ej
- (IBAction)tab1:(id)sender {
UIViewController *viewController1 = [self.storyboard instantiateViewControllerWithIdentifier:@"vc1"];
_container.view = viewController1.view;
selectedViewController = viewController1;
}
para activar la vista, apareció y llamamos removeChildViewController, didMoveToParent, addChildViewController, didMoveToParent
Actualización : UITabBarController es la forma recomendada de ir, como descubrió anteriormente. En caso de que desee tener una altura personalizada, aquí tiene un buen comienzo: mi forma de personalizar la barra de pestañas de UITabBarController - respuesta de
A partir de iOS 5+, tiene acceso para personalizar la apariencia a través de esta API; Referencia de protocolo UIAppearance . Aquí hay un buen tutorial para eso: Cómo personalizar el fondo y la apariencia de la barra de pestañas
La forma más obvia de lograr lo que está buscando es simplemente administrar 3 contenedores diferentes (son UIViews simples) e implementar cada uno de ellos para mantener la vista de contenido que necesita para cada pestaña (use la propiedad oculta de los contenedores).
Aquí hay un ejemplo de lo que es posible lograr con diferentes contenedores:
Estos contenedores de "intercambio" se pueden animar, por supuesto. Acerca de su auto-respuesta, probablemente eligió la forma correcta de hacerlo.