bar ios iphone cocoa-touch uinavigationbar uitoolbar

uinavigationbar ios



Creando un botón de flecha izquierda(como el estilo de "espalda" de UINavigationBar) en una barra de UITool (23)

Me encantaría crear un botón "atrás" de flecha izquierda en una UIToolbar .

Por lo que puedo decir, la única forma de obtener uno de estos es dejar UINavigationController en la configuración predeterminada y usa uno para el elemento de la barra izquierda. Pero no hay forma de que pueda crear uno como un UIBarButtonItem , por lo que no puedo crear uno en un UIToolbar estándar, a pesar de que son muy similares a los UINavigationBar s.

Podría crearlo manualmente con imágenes de botones, pero no puedo encontrar las imágenes de origen en ningún lugar. Tienen bordes de canal alfa, por lo que las capturas de pantalla y el corte no obtendrán resultados muy versátiles.

¿Alguna idea más allá de la captura de pantalla para cada tamaño y combinación de colores que pretendo usar?

Actualización: POR FAVOR DEJE de esquivar la pregunta y sugiera que no debería preguntar esto y debería usar UINavigationBar . Mi aplicación es Instapaper Pro. Solo muestra una barra de herramientas inferior (para ahorrar espacio y maximizar el área de contenido legible), y deseo colocar un botón Atrás con forma de flecha izquierda en la parte inferior.

Decirme que no debería hacer esto no es una respuesta y ciertamente no merece una recompensa.


El Método Unicode

Creo que es mucho más fácil usar un carácter Unicode para hacer el trabajo. Puedes mirar a través de las flechas buscando en Google Triángulos Unicode o Flechas Unicode . Comenzando con iOS6, Apple cambió el carácter para que fuera un personaje emoji con un borde. Para deshabilitar el borde, agrego el selector de variación Unicode 0xFE0E.

NSString *backArrowString = @"/U000025C0/U0000FE0E"; //BLACK LEFT-POINTING TRIANGLE PLUS VARIATION SELECTOR UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.leftButtonItem = backBarButtonItem;

El bloque de código es solo para la demo. Funcionaría en cualquier botón que acepte un NSString.

Para obtener una lista completa de los caracteres, busque en Google el carácter Unicode y lo que desea. Aquí está la entrada para el Triángulo Negro a la Izquierda .

Resultado


¿Por qué estás haciendo esto? Si quieres algo que se parece a una barra de navegación, usa UINavigationBar.

Las barras de herramientas tienen un estilo visual específico asociado a ellas. Las Directrices de interfaz humana para el estado del iPhone:

Aparece una barra de herramientas en el borde inferior de la pantalla y contiene botones que realizan acciones relacionadas con los objetos en la vista actual.

Luego da varios ejemplos visuales de íconos aproximadamente cuadrados sin texto. Les insto a seguir el HIG en esto.


Bueno, no es necesario que tenga un botón diferente para cada tamaño, puede usar [UIImage stretchableImageWithLeftCapWidth:topCapHeight:] , pero lo único que he encontrado son imágenes personalizadas.


Descubrí que al usar el siguiente código simple hizo el truco (requiere una imagen personalizada en el paquete):

// Creates a back button instead of default behaviour (displaying title of previous screen) UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(backAction)]; tipsDetailViewController.navigationItem.leftBarButtonItem = backButton; [backButton release];


Ejemplo en Swift 3, con un botón anterior y otro en la parte superior derecha.

let prevButtonItem = UIBarButtonItem(title: "/u{25C0}", style: .plain, target: self, action: #selector(prevButtonTapped)) let nextButtonItem = UIBarButtonItem(title: "/u{25B6}", style: .plain, target: self, action: #selector(nextButtonTapped)) self.navigationItem.rightBarButtonItems = [nextButtonItem, prevButtonItem]


Es fácil de hacer con Interface Builder en Xcode 5.x

  • usa la barra de herramientas y el elemento del botón de barra de la biblioteca de objetos

  • en el inspector de Atributos del botón edita la sección Imagen con la imagen del botón Atrás

¡Hecho!


Estaba intentando hacer lo mismo, pero quería que el botón Atrás estuviera en la barra de navegación. (En realidad necesitaba un botón de retroceso, eso haría más que solo regresar, así que tuve que usar la propiedad leftBarButtonItem). Intenté lo que AndrewS sugirió, pero en la barra de navegación no se vería como debería, ya que el UIButton se convirtió en un UIBarButtonItem.

Pero encontré una manera de evitar esto. De hecho, simplemente coloqué una vista UIV debajo del botón UIB y configuré la vista personalizada para el artículo UIBarButtonItem Aquí está el código, si alguien lo necesita:

// initialize button and button view UIButton *backButton = [UIButton buttonWithType:101]; UIView *backButtonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, backButton.frame.size.width, backButton.frame.size.height)]; [backButton addTarget:self action:@selector(backButtonTouched:) forControlEvents:UIControlEventTouchUpInside]; [backButton setTitle:@"Back" forState:UIControlStateNormal]; [backButtonView addSubview:backButton]; // set buttonview as custom view for bar button item UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButtonView]; self.navigationItem.leftBarButtonItem = backButtonItem; // push item to navigationbar items [self.navigationController.navigationBar setItems:[NSArray arrayWithObject:backButtonItem]];


Esto es lo que terminé haciendo después de buscar todas estas soluciones y otras. Utiliza un png estirable extraído de las imágenes de stock de UIKit. De esta manera usted puede configurar el texto a lo que sea que mientas

// Generate the background images UIImage *stretchableBackButton = [[UIImage imageNamed:@"UINavigationBarDefaultBack.png"] stretchableImageWithLeftCapWidth:14 topCapHeight:0]; UIImage *stretchableBackButtonPressed = [[UIImage imageNamed:@"UINavigationBarDefaultBackPressed.png"] stretchableImageWithLeftCapWidth:13 topCapHeight:0]; // Setup the UIButton UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; [backButton setBackgroundImage:stretchableBackButton forState:UIControlStateNormal]; [backButton setBackgroundImage:stretchableBackButtonPressed forState:UIControlStateSelected]; NSString *buttonTitle = NSLocalizedString(@"Back", @"Back"); [backButton setTitle:buttonTitle forState:UIControlStateNormal]; [backButton setTitle:buttonTitle forState:UIControlStateSelected]; backButton.titleEdgeInsets = UIEdgeInsetsMake(0, 5, 2, 1); // Tweak the text position NSInteger width = ([backButton.titleLabel.text sizeWithFont:backButton.titleLabel.font].width + backButton.titleEdgeInsets.right +backButton.titleEdgeInsets.left); [backButton setFrame:CGRectMake(0, 0, width, 29)]; backButton.titleLabel.font = [UIFont boldSystemFontOfSize:13.0f]; [backButton addTarget:self action:@selector(yourSelector:) forControlEvents:UIControlEventTouchDown]; // Now add the button as a custom UIBarButtonItem UIBarButtonItem *backButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease]; self.navigationItem.leftBarButtonItem = backButtonItem;


La biblioteca Three20 tiene una manera de hacer esto:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle: @"Title" style:UIBarButtonItemStylePlain target:self action:@selector(foo)]; UIColor* darkBlue = RGBCOLOR(109, 132, 162); TTShapeStyle* style = [TTShapeStyle styleWithShape:[TTRoundedLeftArrowShape shapeWithRadius:4.5] next: [TTShadowStyle styleWithColor:RGBCOLOR(255,255,255) blur:1 offset:CGSizeMake(0, 1) next: [TTReflectiveFillStyle styleWithColor:darkBlue next: [TTBevelBorderStyle styleWithHighlight:[darkBlue shadow] shadow:[darkBlue multiplyHue:1 saturation:0.5 value:0.5] width:1 lightSource:270 next: [TTInsetStyle styleWithInset:UIEdgeInsetsMake(0, -1, 0, -1) next: [TTBevelBorderStyle styleWithHighlight:nil shadow:RGBACOLOR(0,0,0,0.15) width:1 lightSource:270 next:nil]]]]]]; TTView* view = [[[TTView alloc] initWithFrame:CGRectMake(0, 0, 80, 35)] autorelease]; view.backgroundColor = [UIColor clearColor]; view.style = style; backButton.customView = view; self.navigationItem.leftBarButtonItem = backButton;


No estoy seguro de si esto funcionaría, pero podría intentar crear un UINavigationController con la configuración predeterminada para crear el botón, encontrar el botón en la jerarquía de subvistas del controlador de navegación, llamar a removeFromSuperview , destruir el controlador de navegación y luego agregar el botón como una subvista de su barra de herramientas. También es posible que deba retain y el botón antes de llamar a removeFromSuperview (y luego release después de agregarlo como una subvista de su barra de herramientas) para evitar que se lo desasigne durante el proceso.


Para crear una imagen para la barra de herramientas de la UIT, cree un png en photoshop y DONDE NUNCA HAY CUALQUIER color que lo ponga blanco, y donde sea alfa = 0, entonces lo deja solo.

El SDK en realidad pone el borde alrededor del icono que has hecho y lo vuelve blanco sin que tengas que hacer nada.

Mira, esto es lo que hice en Photoshop para mi botón de avance (obviamente lo cambié por el botón de atrás):

http://twitpic.com/1oanv

Y esto es lo que parecía en Interface Builder.

http://twitpic.com/1oaoa


Para hacer un UIButton con una flecha bastante cerca (no soy un diseñador;) a la flecha trasera del sistema iOS 7:

Estándar:

Apple SD Gothic Neo

En Xcode:

  • Enfóquese en el campo de valor de título del botón (o cualquier otra vista / control con contenido de texto)
  • Abrir Edición -> Caracteres Especiales
  • Seleccione el grupo de paréntesis y haga doble clic en el carácter ''<''
  • Cambie la fuente a: Apple SD Gothic Neo, Regular con el tamaño deseado (por ejemplo, 20)
  • Cambia el color como quieras

La respuesta de Ref @ staticVoidMan a la flecha de tipo Back en iOS 7


Prueba esto. Estoy seguro de que no necesita una imagen del botón Atrás para crear una de ellas.

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered target:self action:@selector(yourSelectorGoesHere:)]; self.navigationItem.backBarButtonItem = backButton;

Eso es todo lo que tienes que hacer :)


Puede encontrar las imágenes de origen extrayéndolas de Other.artwork en UIKit $ {SDKROOT} /System/Library/Frameworks/UIKit.framework/Other.artwork. La comunidad modding tiene algunas herramientas para extraerlos, here . Una vez que extraiga la imagen, puede escribir algo de código para cambiar el color según sea necesario y establecerla como la imagen del botón. Si puede o no enviar una cosa así (ya que está incorporando ilustraciones derivadas) puede ser un poco arriesgado, así que tal vez quiera hablar con un abogado.


Rápido

// create button var backButton = UIButton(type: 101) // left-pointing shape! backButton.addTarget(self, action: #selector(self.backAction), for: .touchUpInside) backButton.setTitle("Back", for: .normal) // create button item -- possible because UIButton subclasses UIView! var backItem = UIBarButtonItem(customView: backButton) // add to toolbar, or to a navbar (you should only have one of these!) toolbar.items = [backItem] navItem.leftBarButtonItem = backItem


Si desea evitar dibujarlo usted mismo, puede usar la clase de indocumentados: UINavigationButton con estilo 1. Esto, por supuesto, puede impedir que su solicitud sea aprobada ... / John


Solución SIN usar un png. Basado en esta respuesta SO: Agregar la pequeña flecha al lado derecho de una celda en una celda TableView de iPhone

¡Solo moviendo el UITableViewCell horizontalmente!

UIButton *btnBack = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 70, 20)]; // Add the disclosure CGRect frm; UITableViewCell *disclosure = [[UITableViewCell alloc] init]; disclosure.transform = CGAffineTransformScale(CGAffineTransformIdentity, -1, 1); frm = self.btnBack.bounds; disclosure.frame = CGRectMake(frm.origin.x, frm.origin.y, frm.size.width-25, frm.size.height); disclosure.accessoryType = UITableViewCellAccessoryDisclosureIndicator; disclosure.userInteractionEnabled = NO; [self.btnBack addSubview:disclosure]; // Add the label UILabel *lbl = [[UILabel alloc] init]; frm = CGRectOffset(self.btnBack.bounds, 15, 0); lbl.frame = frm; lbl.textAlignment = NSTextAlignmentCenter; lbl.text = @"BACK"; [self addSubview:lbl];


Tuve un problema similar, y salí de una biblioteca PButton . Y la muestra es el botón de navegación hacia atrás, como el botón, que se puede usar en cualquier lugar como un botón personalizado.

Algo como esto:


Usé el siguiente psd que obtuve de http://www.teehanlax.com/blog/?p=447

http://www.chrisandtennille.com/pictures/backbutton.psd

Luego, acabo de crear una UIView personalizada que uso en la propiedad customView del elemento de la barra de herramientas.

Funciona bien para mi

Edición: Como lo señaló PrairieHippo , maralbjo descubrió que al usar el siguiente código simple, el truco (requiere una imagen personalizada en el paquete) debe combinarse con esta respuesta. Así que aquí hay un código adicional:

// Creates a back button instead of default behaviour (displaying title of previous screen) UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back_arrow.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(backAction)]; tipsDetailViewController.navigationItem.leftBarButtonItem = backButton; [backButton release];


Si no quiere molestarse con los archivos de imagen, la forma de la flecha se puede dibujar en una subclase UIView con el siguiente código:

- (void)drawRect:(CGRect)rect { float width = rect.size.width; float height = rect.size.height; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextBeginPath(context); CGContextMoveToPoint(context, width * 5.0/6.0, height * 0.0/10.0); CGContextAddLineToPoint(context, width * 0.0/6.0, height * 5.0/10.0); CGContextAddLineToPoint(context, width * 5.0/6.0, height * 10.0/10.0); CGContextAddLineToPoint(context, width * 6.0/6.0, height * 9.0/10.0); CGContextAddLineToPoint(context, width * 2.0/6.0, height * 5.0/10.0); CGContextAddLineToPoint(context, width * 6.0/6.0, height * 1.0/10.0); CGContextClosePath(context); CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor); CGContextFillPath(context); }

donde la vista de flecha es proporcional a un ancho de 6.0 y una altura de 10.0


ADVERTENCIA: hay informes de que esto no funcionará en iOS 6. Esto podría funcionar solo en versiones anteriores del sistema operativo. Evidentemente, al menos un desarrollador ha rechazado su aplicación por usar este truco (vea los comentarios). Úselo bajo su propio riesgo. Usar una imagen (ver la respuesta anterior) puede ser una solución más segura.

Esto se puede hacer sin agregar sus propios archivos de imagen usando el botón sekr1t tipo 101 para obtener la forma correcta. Para mí, el truco fue descubrir que podría usar initWithCustomView para crear el objeto BarButtonItem . Personalmente lo necesitaba para una barra de navegación dinámica en lugar de una toolbar , pero la probé con una barra de herramientas y el código es casi el mismo:

// create button UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape! [backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside]; [backButton setTitle:@"Back" forState:UIControlStateNormal]; // create button item -- possible because UIButton subclasses UIView! UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; // add to toolbar, or to a navbar (you should only have one of these!) [toolbar setItems:[NSArray arrayWithObject:backItem]]; navItem.leftBarButtonItem = backItem;

Si está haciendo esto en una barra de herramientas, tendrá que modificar la forma en que configura los elementos, pero eso depende del resto de su código y lo dejo como un ejercicio para el lector. : P Esta muestra funcionó para mí (compilada y ejecutada).

Blah blah, lea el HIG, no use funciones no documentadas, y todo eso. Solo hay seis tipos de botones compatibles y este no es uno de ellos.


En primer lugar tienes que encontrar una imagen del botón Atrás. Usé una aplicación agradable llamada Extractor que extrae todos los gráficos del iPhone. En iOS7 logré recuperar la imagen llamada UINavigationBarBackIndicatorDefault y estaba en color negro, ya que necesitaba un tinte rojo , cambio el color a rojo con Gimp.

EDITAR:

Como mencionó btate en su comentario, no es necesario cambiar el color con el editor de imágenes. El siguiente código debería hacer el truco:

imageView.tint = [UIColor redColor]; imageView.image = [[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Luego creé una vista que contiene una imageView con esa flecha, una etiqueta con el texto personalizado y en la parte superior de la vista tengo un botón con una acción. Luego agregué una animación simple (desvanecimiento y traducción).

El siguiente código simula el comportamiento del botón Atrás, incluida la animación.

-(void)viewWillAppear:(BOOL)animated{ UIImageView *imageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UINavigationBarBackIndicatorDefault"]]; [imageView setTintColor:[UIColor redColor]]; UILabel *label=[[UILabel alloc] init]; [label setTextColor:[UIColor redColor]]; [label setText:@"Blog"]; [label sizeToFit]; int space=6; label.frame=CGRectMake(imageView.frame.origin.x+imageView.frame.size.width+space, label.frame.origin.y, label.frame.size.width, label.frame.size.height); UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0, label.frame.size.width+imageView.frame.size.width+space, imageView.frame.size.height)]; view.bounds=CGRectMake(view.bounds.origin.x+8, view.bounds.origin.y-1, view.bounds.size.width, view.bounds.size.height); [view addSubview:imageView]; [view addSubview:label]; UIButton *button=[[UIButton alloc] initWithFrame:view.frame]; [button addTarget:self action:@selector(handleBack:) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:button]; [UIView animateWithDuration:0.33 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ label.alpha = 0.0; CGRect orig=label.frame; label.frame=CGRectMake(label.frame.origin.x+25, label.frame.origin.y, label.frame.size.width, label.frame.size.height); label.alpha = 1.0; label.frame=orig; } completion:nil]; UIBarButtonItem *backButton =[[UIBarButtonItem alloc] initWithCustomView:view]; } - (void) handleBack:(id)sender{ }

EDITAR:

En lugar de agregar el botón, en mi opinión, el mejor enfoque es utilizar un reconocedor de gestos.

UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBack:)]; [view addGestureRecognizer:tap]; [view setUserInteractionEnabled:YES];


self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;

Funciona para mi. Utilicé esto cuando tenía más pestañas y luego cabía en la barra de pestañas, y un controlador de vista insertado desde "Más" anulaba el elemento de la barra izquierda en su viewDidLoad.