Quiero usar personalizado botón atrás. en iOS 6, todo es perfecto, pero iOS 7 es extraño.

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[[UIImage imageNamed:@"back_button_normal"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12.0, 0, 12.0)] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

primera, que no tiene iOS 7 flecha y no la imagen de fondo.

(Federación regional)

iOS 7 personalizados botón atrás

entonces, si usted presiona el botón de la imagen de fondo aparece. También tuve la imagen de fondo conjunto para UIControlStateHighlighted estado y cuando mantenga pulsado el botón resaltado de la imagen aparece demasiado. Después de cualquier botón atrás una vez que se presiona todos los botones de la espalda tiene imagen de fondo.

iOS 7 personalizados botón atrás

PERO! Si usted presente modal de controlador de vista, descartarla, a continuación, presione cualquier controlador de vista – iOS 7 flecha aparecerá en cada botón atrás.

Yo uso DP5. Es que un UIKit error?

PS También he probado a crear de nuevo el botón de forma manual, utilizando UIBarButtonItem, establecer la imagen de fondo, entonces self.navigationItem.backBarButtonItem = barButtonItem; no ayuda.
Entonces traté de ajustar imagen de fondo para personas con discapacidad del estado y el cambio de propiedad enabled de mi botón de la barra de punto, no ayuda demasiado.

iOS 7 personalizados botón atrás

  • iOS 7 es todavía bajo NDA… Usted debe buscar en UINavigationBar nuevas propiedades introducido con iOS 7, no podría ser una solución para que no
  • ver este hilo: stackoverflow.com/questions/18099073/…
  • Me estoy enfrentando el mismo problema amigo. Te encontraste alguna solución para esto?
InformationsquelleAutor storoj | 2013-09-16

12 Comentarios

  1. 50

    Esto no es un error, esta Back button se ve en iOS 7. Por ejemplo:

    iOS 7 personalizados botón atrás

    Probablemente, usted debe utilizar el nuevo concepto para su aplicación, y no para establecer la imagen de fondo para el botón atrás en iOS 7.

    Si usted todavía desea botón atrás tienen el mismo como se veía en iOS6 que probablemente debería crear los botones de la espalda de forma manual:

    - (void)loadView
    {
        [super loadView];
    
        UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 60.0f, 30.0f)];
        UIImage *backImage = [[UIImage imageNamed:@"back_button_normal.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12.0f, 0, 12.0f)];
        [backButton setBackgroundImage:backImage  forState:UIControlStateNormal];
        [backButton setTitle:@"Back" forState:UIControlStateNormal];
        [backButton addTarget:self action:@selector(popBack) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        self.navigationItem.leftBarButtonItem = backButtonItem;
    }
    
    -(void) popBack {
      [self.navigationController popViewControllerAnimated:YES];
    }

    Editar: No romper Gesto de (Aquí hay una fuente)

    self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
    • Gracias por la respuesta. Por desgracia, es demasiado caro para gestionar el botón atrás el uso de leftBarButtonItem en el proyecto existente, así que decidimos seguir la pauta y quitar imágenes de fondo para los botones de la barra en iOS 7. Se ve realmente bien.
    • Es una buena decisión para avanzar hacia el nuevo iOS7 concepto
    • Cómo ocultar la flecha de atrás?
    • si u utilizar este método el pase atrás gesto no funciona
    • Demasiado extensa. Usted no necesita init itwith botón personalizado. Se pueden hacer las cosas más fácil mediante la personalización de la apariencia de este único BarButtonItem para parecerse a good ol’ botón atrás.
  2. 22

    La imagen de fondo personalizada que no aparecen en el primer empuje se fija en iOS 7 GM.

    Para ocultar trasera estándar indicador de utilizar este código:

    if ([UINavigationBar instancesRespondToSelector:@selector(setBackIndicatorImage:)]) { //iOS 7
        [navigationBarAppearance setBackIndicatorImage:[UIImage imageNamed:@"transparent_1px"]];
        [navigationBarAppearance setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"transparent_1px"]];
    }
  3. 13

    La imagen de fondo personalizada no aparecen inicialmente no se fija en iOS7 GM o final, como lo que puedo decir. Veo el mismo problema. Ella parece ser una Manzana error; la vista privada de Apple utiliza simplemente no obtener una setNeedsDisplay llame cuando lo necesite en la presentación inicial. Hacer nada que provoca que la llamada debe fijar — como pulsar sobre ella (que es muy probable que los cambios de estado interno por lo que llama a setNeedsDisplay en sí mismo), o la interposición de un modal hacia arriba (lo cual, probablemente, las fuerzas de una nueva visualización de la vista de jerarquía en la siguiente viewWillAppear: llame).

    Utilizando leftBarItems lugar también puede funcionar, pero que puede causar un montón de problemas de mantenimiento con el código ya existente (algunas pantallas pueden tener sus propias izquierda artículos, esperando que cuando vuelva a nil que restaurar el original elemento, por ejemplo).

    Como se ha mencionado, lo ideal sería ser capaz de cambiar a un sin bordes mirada en iOS7, lo que significa que el error no es realmente aparente (ya que no hay ninguna imagen de fondo). Para algunos iOS6/iOS7 situaciones de transición a pesar de que puede ser difícil (un montón de pantallas y/o la necesidad de apoyar las antiguas versiones de iOS por un tiempo y demasiado duro para tener dos miradas implementado, y no se ve bien sin fronteras, sin otros cambios). Si ese es el caso, la siguiente revisión debería funcionar:

    #import <objc/runtime.h>
    
    @implementation UINavigationBar (BackButtonDisplayFix)
    
    + (void)load
    {
        if ([UIDevice currentDevice].systemVersion.intValue >= 7)
        {
            /*
             * We first try to simply add an override version of didAddSubview: to the class.  If it
             * fails, that means that the class already has its own override implementation of the method
             * (which we are expecting in this case), so use a method-swap version instead.
             */
            Method didAddMethod = class_getInstanceMethod(self, @selector(_displaybugfixsuper_didAddSubview:));
            if (!class_addMethod(self, @selector(didAddSubview:),
                                 method_getImplementation(didAddMethod),
                                 method_getTypeEncoding(didAddMethod)))
            {
                Method existMethod = class_getInstanceMethod(self, @selector(didAddSubview:));
                Method replacement = class_getInstanceMethod(self, @selector(_displaybugfix_didAddSubview:));
                method_exchangeImplementations(existMethod, replacement);
            }
        }
    }
    
    - (void)_displaybugfixsuper_didAddSubview:(UIView *)subview
    {
        [super didAddSubview:subview];
        [subview setNeedsDisplay];
    }
    
    - (void)_displaybugfix_didAddSubview:(UIView *)subview
    {
        [self _displaybugfix_didAddSubview:subview]; //calls the existing method
        [subview setNeedsDisplay];
    }
    
    @end

    Nota: UINavigationBar actualmente tiene un reemplazo del método en cuestión, por lo que espero que la method_exchangeImplementations estilo para ser utilizado. Acabo de añadir las otras cosas, para la seguridad en caso de que Apple cambia su código. Podemos ir sin fronteras de nosotros mismos, pero encontré este método funcionaba como una opción (hasta un más exhaustivo de la interfaz de usuario de elevación), al menos.

    Nota adicional: Este error parece ser fijo en iOS 7.1. Así, el parche puede ser conditionalized instalar sólo los métodos si se ejecutar >= 7.0 y < 7.1.

    • Gracias! Yo uso este por subclases de la UINavigationBar y la invalidación de la didAddSubview.
  4. 6

    Hay una solución mejor, que no implica método swizzling.

    Necesita agregar UINavigationViewControllerDelegate método en algún lugar de su aplicación.

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    dispatch_async(dispatch_get_main_queue(), ^{
        [[navigationController.navigationBar subviews] makeObjectsPerformSelector:@selector(setNeedsDisplay)];
    });

    }

    • Esto es simple pero con un gran uno esta solucionado mi problema
    • No me funciona (iOS 12)
  5. 3

    Mi solución es para iOS 7 y anteriores.

    Al principio, hacer copia de botón invisible.

    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];

    a continuación, ajuste predeterminado backIndicatorImage de botón atrás el uso personalizado de imagen.

    [UINavigationBar appearance].backIndicatorImage = [[UIImage imageNamed:@"topbar_icon_back_n.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    [UINavigationBar appearance].backIndicatorTransitionMaskImage = [[UIImage imageNamed:@"topbar_icon_back_p.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

    En este punto, hacer personalizada UINavigationBar para cambiar el tamaño _UINavigationBarBackIndicatorView que contiene más de backIndicatorImage.

    const CGPoint SANavigationBarOffset = { -8, 11.5};
    
    @implementation SANavigationBar
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
    
        //set back button position
        NSArray *classNamesToReposition = @[@"_UINavigationBarBackIndicatorView"];
    
        for (UIView *view in [self subviews]) {
            if ([classNamesToReposition containsObject:NSStringFromClass([view class])]) {
                CGRect frame = [view frame];
                frame.origin.x = 0;
                frame.origin.y = 0;
    
                [view setFrame:frame];
            }
        }
    }
    
    @end

    a continuación, establezca como mi navigationBar

    //set custom NavagationBar for back button position
    [self.navigationController setValue:[[SANavigationBar alloc] init] forKey:@"navigationBar"];
    • Muchas gracias! Los dos primeros pasos son suficientes para cambiar el valor predeterminado de la flecha de la imagen y ocultar el botón atrás de texto.
  6. 1

    Botón agregar como elemento de navegación en ios7 como a continuación

     UIButton *btnAdd = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];
    
            [btnAdd setContentMode:UIViewContentModeScaleAspectFit];
    
            [btnAdd setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];
    
            [btnAdd addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    
            UIBarButtonItem *btnAdd = [[UIBarButtonItem alloc] initWithCustomView:imView];
    
            self.navigationItem.rightBarButtonItem = btnAdd;
  7. 1

    Uso de Swift puede añadir una extensión:

    extension UIViewController: UIGestureRecognizerDelegate {
        func popBack() {
            self.navigationController?.popViewControllerAnimated(true)
        }
    
        func enableCustomBackButtom() {
            self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon-back"), style: UIBarButtonItemStyle.Plain, target: self, action:"popBack")
    
            self.navigationController?.interactivePopGestureRecognizer.delegate = self
        }
    }

    Y en su UIViewController uso como esta:

    self.enableCustomBackButtom()
  8. 0

    Lo hice de proporcionar el mismo comportamiento que en iOS6 (aviso que navigationBar es el UINavigationBar), asegúrese de que navigationBar tiene un topItem

    UINavigationItem *topItemNavigation = [navigationBar topItem];
    
    UIBarButtonItem *barButtonTopItemNavigation = [[UIBarButtonItem alloc] initWithTitle:topItemNavigation.title style:UIBarButtonItemStyleBordered target:nil action:nil];
    
    [barButtonTopItemNavigation setBackButtonBackgroundImage:YOUR_IMAGE_BACKGROUND forState:UIControlStateNormal barMetrics:UIBarMetricsDefault ];
                [topItemNavigation setBackBarButtonItem: barButtonTopItemNavigation];
            }
  9. 0

    Mi solución fue la de escribir una categoría en la UINavigationItem. Esto es para iOS7.

    - (void)mdSetCustomBackButton:(UINavigationController *)navigationController
    {
        MDBackButton *backButton = [[MDBackButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 44.0, 44.0) navigationController:navigationController];
        [backButton addTarget:self action:@selector(popBack:) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        [self setLeftBarButtonItem:barButtonItem];
        [navigationController.interactivePopGestureRecognizer setDelegate:(id<UIGestureRecognizerDelegate>)self];
    }
    
    - (void)popBack:(MDBackButton *)sender
    {
        [sender.navigationController popViewControllerAnimated:YES];
    }

    Y subclase UIButton para agregar un UINavigationController de la propiedad (para el pop y el conjunto de pase de nuevo delegado).

    @property (nonatomic, weak) UINavigationController *navigationController;
    
    @implementation MDBackButton
    
    - (id)initWithFrame:(CGRect)frame navigationController:(UINavigationController *)navigationController
    {
        self = [super initWithFrame:frame];
        if(self){
            _navigationController = navigationController;
            [self setImage:[UIImage imageNamed:@"back_button"] forState:UIControlStateNormal];
        }
        return self;
    }
  10. 0

    Este es un trabajo para mí:

    - (void)setCustomNavigationBackButton
    {    
      self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    
      UIImage *myIcon = [self imageWithImage:[UIImage imageNamed:@"backbutton.png"] scaledToSize:CGSizeMake(20, 20)];
    
      self.navigationController.navigationBar.backIndicatorImage = myIcon;
      self.navigationController.navigationBar.backIndicatorTransitionMaskImage = myIcon;
    }
    
    - (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize 
    {
      //UIGraphicsBeginImageContext(newSize);
      //In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
      //Pass 1.0 to force exact pixel size.
      UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
      [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return newImage;
    }

    También, la fuente personalizada con color personalizado:

    //self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:
     @{NSForegroundColorAttributeName:[UIColor whiteColor],
       NSFontAttributeName:[UIFont fontWithName:@"Signika-Bold" size:20]}
    
    forState:UIControlStateNormal];

    Referencia: https://stackoverflow.com/a/2658801/1371949

  11. 0

    Puedo usar estos códigos de abajo, que funciona en iOS 8

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    button.exclusiveTouch = YES;
    button.titleLabel.font = [UIFont systemFontOfSize:14.0];
    [button setTitleColor:kWhiteColor forState:UIControlStateNormal];
    [button setTitleColor:[UIColor colorWithRed:1/255.0 green:36/255.0 blue:60/255.0 alpha:1.0] forState:UIControlStateHighlighted];
    [button setTitle:@"Back" forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"barbutton_back"] forState:UIControlStateNormal];
    [button setImageEdgeInsets:UIEdgeInsetsMake(1.0, 0.0, 0.0, 0.0)];
    CGSize fontSize = [button.titleLabel sizeThatFits:CGSizeMake(100.0, 30.0)];
    button.frame = CGRectMake(0.0, 0.0, button.imageView.image.size.width+fontSize.width, 30.0);
    UIBarButtonItem *barbtn = [[UIBarButtonItem alloc] initWithCustomView:button];
    //fix iOS 7 left margin
    UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    negativeSpacer.width = -10;
    self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:negativeSpacer,barbtn, nil];
  12. -1
    -(void) viewWillAppear:(BOOL)animated
    {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setFrame:CGRectMake(0, 0, 30, 44)];
        [btn setImage:[UIImage imageNamed:@"btnBack.png"] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(PopToView) forControlEvents:UIControlEventTouchUpInside];
        UIBarButtonItem *btnBack = [[UIBarButtonItem alloc] initWithCustomView:btn];
        [btnBack setTintColor:[UIColor whiteColor]];
        [[self.navigationController navigationItem] setLeftBarButtonItem:btnBack];
    
    }

Dejar respuesta

Please enter your comment!
Please enter your name here