ios uiview uiviewcontroller uiwindow

ios - Hacer que un botón sea persistente en todos los controladores de vista



uiview uiviewcontroller (5)

Cree un objeto singleton que contenga el botón para que todos los controladores de vista puedan hacer referencia a él y agregarlo a su subvista o agregarlo a la ventana directamente.

SomeClass.h @property (nonatomic) UIButton *yourButton; +(SomeClass*)sharedSomeClass; SomeClass.m @synthesize yourButton = _yourButton; -(id)init { self = [super init]; if(self) { _yourButton = [UIButton new]; //Other settings you want for your button } return self; } +(SomeClass)sharedSomeClass { static SomeClass *sharedSomeClass; if (!sharedSomeClass) sharedSomeClass = [[super allocWithZone:nil]init]; return sharedSomeClass; } +(void)allocWithZone:(NSZone*)zone { return [self sharedSomeClass]; }

Si lo desea, puede acceder a la ventana directamente de esta manera:

UIWindow *mainwindow = [[[UIApplication sharedApplication]delegate]window];

importe SomeClass.h en sus controladores de vista y acceda al botón desde cualquier lugar

#import "SomeClass.h" SomeClass *someClass = [SomeClass sharedSomeclass]; UIButton *localButton = someClass.yourButton;

Quiero tener un botón persistente en la esquina inferior derecha de mi aplicación. Durante todas las transiciones de vista, el botón debe permanecer estático. Tengo problemas para decidir a qué vista agregar el botón. Sé que el botón debe estar almacenado en AppDelegate, pero no sé en qué otra vista sería lógico agregarlo excepto la ventana. Una desventaja de agregarlo a la ventana es que cuando hay una aplicación ejecutándose en segundo plano (es decir, el teléfono), el relleno de la barra de estado agregado empujará hacia abajo la ventana. En general, agregarlo a la ventana parece ser una solución hacky, ¿algún pensamiento?


Potencialmente, podría tener 1 controlador de vista principal "raíz", y todos los demás controladores de vista podrían ser controladores de vista infantil, con sus vistas como vistas secundarias. Entonces tendrían su contenido, y el botón estaría en el controlador de vista "raíz". Pero esto parece tan incompleto y hacky como ponerlo en la ventana, y probablemente sea menos conveniente.


Prueba a subclasificar la clase UIViewController y crea la tuya propia con el botón


Sí, agregarlo a la ventana UIWW sería extremadamente hacky y meticuloso.

Guiones gráficos

Si usa Storyboards e iOS 5.0 en adelante, debería poder usar vistas de contenedor y hacer algo como esto:

Aquí hay otra imagen que muestra la estructura bastante simplista del primer Controlador de Vista:

El controlador de vista de la izquierda tiene un contenedor y luego una vista que contiene el botón encima. El contenedor indica que el controlador de navegación (directamente a la derecha) debe aparecer dentro de sí mismo, esa relación se muestra con la flecha =([])=> (formalmente conocida como segue de inserción ). Finalmente, el controlador de navegación define su controlador de vista raíz al de la derecha.

En resumen, la primera vista controla los panqueques, en la vista del contenedor con el botón en la parte superior, por lo que todo lo que sucede dentro debe tener el botón en la parte superior.

Usando childViewControllers

alias El modo "Odio guiones gráficos y cachorros"

Utilizando una estructura similar a la versión de Storyboard, puede crear el controlador de vista base con su botón y luego agregar la vista que se convertirá en la nueva "raíz" de la aplicación, debajo.

Para dejarlo en claro, llamemos al controlador de una vista que mantiene el botón FakeRootViewController , y al controlador de vista que, para todos los fines prácticos, será la raíz de la aplicación: RootViewController . Todos los controladores de vista posteriores ni siquiera sabrán que FakeRootViewController encima de todos los demás.

FakeRootViewController.m

// The "real" root #import "RootViewController.h" // Call once after the view has been set up (either through nib or coded). - (void)setupRootViewController { // Instantiate what will become the new root RootViewController *root = [[RootViewController alloc] <#initWith...#>]; // Create the Navigation Controller UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root]; // Add its view beneath all ours (including the button we made) [self addChildViewController:nav]; [self.view insertSubview:nav.view atIndex:0]; [nav didMoveToParentViewController:self]; }

AppDelegate.m

#import "FakeRootViewController.h" - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; FakeRootViewController *fakeRoot = [[FakeRootViewController alloc] <#initWith...#>]; self.window.rootViewController = fakeRoot; [self.window makeKeyAndVisible]; return YES; }

De esta forma, puede tener todos los beneficios de insertar el botón en la ventana, sin toda la culpa y "¿Debo ser realmente un programador?" que causa


Yo uso este botón:

@interface UIPopUpButton : UIImageView <UIPopoverControllerDelegate, UIActionSheetDelegate> { UIPopoverController* popoverController; Class popoverClass; } - (id) initWithPoint: (CGPoint) point; - (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event; + (id) buttonAtPoint: (CGPoint) point; + (id) buttonAtOriginalPoint; + (void) unhighlight; + (void) bringButtonToFront; @property (nonatomic, retain) UIPopoverController* popoverController; @property (nonatomic, assign) Class popoverClass; @end #import "UIPopUpButton.h" @implementation UIPopUpButton static UIPopUpButton* button = nil; static CGPoint originalPoint; @synthesize popoverClass; @synthesize popoverController; + (id) buttonAtPoint: (CGPoint) point { if (button == nil) { button = [[UIPopUpButton alloc] initWithPoint: point]; originalPoint = point; button.popoverClass = [UIPopoverController class]; } else { button.frame = CGRectMake(point.x, point.y, button.frame.size.width, button.frame.size.height); } return button; } + (id) buttonAtOriginalPoint { return [self buttonAtPoint: originalPoint]; } + (void) unhighlight { button.highlighted = NO; } + (void) bringButtonToFront { [[UIApplication sharedApplication].keyWindow addSubview: [self buttonAtOriginalPoint]]; } - (id) initWithPoint: (CGPoint) point { UIImage* image1 = [UIImage imageNamed: @"topbutton.png"]; UIImage* image2 = [UIImage imageNamed: @"topbutton.png"]; if ((self = [super initWithImage: image1 highlightedImage: image2])) { self.userInteractionEnabled = YES; self.frame = CGRectMake(point.x, point.y, self.frame.size.width, self.frame.size.height); self.multipleTouchEnabled = NO; } return self; } - (BOOL) isAppCurrStatus { return ([DevToolsClientController sharedInstance].statusOfRootViewController == FrontEndApplication); } - (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event { UITouch* touch = [touches anyObject]; if(touch.view == self) { if (self.popoverController == nil) { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle: @"Please choice operation:" delegate: self cancelButtonTitle: nil destructiveButtonTitle: nil otherButtonTitles: nil]; [actionSheet addButtonWithTitle: @"Cancel"]; actionSheet.cancelButtonIndex = 0; [actionSheet addButtonWithTitle: @"Button 1"]; actionSheet.actionSheetStyle = UIActionSheetStyleDefault; [actionSheet setTag: 0]; [actionSheet setDelegate: self]; [actionSheet showInView: [self superview]]; [actionSheet release]; [actions release]; } else { PopoverMenuController* contentViewController = [[PopoverMenuController alloc] init]; self.popoverController = [[UIPopoverController alloc] initWithContentViewController: contentViewController]; popoverController.delegate = self; [popoverController presentPopoverFromRect: CGRectMake(10.0f, 10.0f, 5.0f, 5.0f) inView: self permittedArrowDirections: UIPopoverArrowDirectionAny animated: YES]; contentViewController.popoverController = self.popoverController; [contentViewController reloadData]; } } else { [self.popoverController dismissPopoverAnimated:YES]; self.popoverController = nil; } } [super touchesBegan: touches withEvent: event]; } #pragma mark UIActionSheetDelegate implementation -(void) actionSheet: (UIActionSheet*) actionSheet clickedButtonAtIndex: (NSInteger) buttonIndex { NSNumber* indexAction = [[NSNumber alloc] initWithInt: buttonIndex - 1]; } - (void) runAction: (NSNumber*) indexAction { [DevToolsPopoverMenuController runAction: [indexAction integerValue]]; } #pragma mark - #pragma mark UIPopoverControllerDelegate implementation - (void) popoverControllerDidDismissPopover: (UIPopoverController*) thePopoverController { if (self.popoverController != nil) { self.popoverController = nil; } } - (BOOL) popoverControllerShouldDismissPopover: (UIPopoverController*) thePopoverController { //The popover is automatically dismissed if you click outside it, unless you return NO here return YES; } @end

llamada:

[UIPopUpButton bringButtonToFront];

Mi botón siempre está en la parte superior.