volver puedo por para inicio home flotante desactivar control como boton atras assistive activar ios swift ios11 xcode9-beta swift4

puedo - barra de navegación rightbaritem error de botón de imagen iOS 11



control por boton iphone (12)

¡Gracias a todos por contribuir! ustedes tienen razón! para xcode9 ios11 necesita poner una restricción.

let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32) let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32) heightConstraint.isActive = true widthConstraint.isActive = true

Este código funciona bien en ios10. recibo mi etiqueta y un botón de imagen que es el perfil de la foto del usuario, circular, redondo ... ok pero cuando ejecuto el simulador xcode 9 ios11, lo extiendo. el marco del botón tiene que ser 32x32, cuando verifico el simulador y obtengo la vista y le digo a xcode que describa la vista obtengo una salida como 170x32 o algo así.

Aquí está mi código.

let labelbutton = UIButton( type: .system) labelbutton.addTarget(self, action:#selector(self.toLogin(_:)), for: .touchUpInside) labelbutton.setTitleColor(UIColor.white, for: .normal) labelbutton.contentHorizontalAlignment = .right labelbutton.titleLabel?.font = UIFont.systemFont(ofSize: 18.00) let button = UIButton(type: .custom) button.addTarget(self, action:#selector(self.toLogin(_:)), for: .touchUpInside) button.frame = CGRect(x: 0, y: 0, width: 32, height: 32) button.setTitleColor(UIColor.white, for: .normal) button.setTitleColor(UIColor.white, for: .highlighted) var buttomItem : UIBarButtonItem = UIBarButtonItem() buttomItem.customView = button buttomItem.target = self buttomItem.action = "ToLogin" var labelItem : UIBarButtonItem = UIBarButtonItem() labelItem.customView = labelbutton labelItem.target = self labelItem.action = "ToLogin" if let user = PFUser.current() { print("LOGIN : checkiando si existe usuario ") labelbutton.setTitle(USERNAME, for: UIControlState.normal) labelbutton.sizeToFit() if(user["profile_photo_url"] != nil) { print(" ENCONTRO PROFILE PHOTO URL NOT NIL Y ES /(user["profile_photo_url"])") let photoURL = user["profile_photo_url"] as! String let a = LoginService.sharedInstance a.downloadImage(url: photoURL, complete: { (complete) in if (complete) { button.setImage(LoginService.sharedInstance.profile_photo! , for: UIControlState.normal) button.layer.cornerRadius = 0.5 * button.bounds.size.width // button.imageView!.contentMode = .scaleAspectFit // button.imageView!.frame = CGRect(x: 0, y: 0, width: 40, height: 40) //button.imageView!.contentMode = .scaleAspectFit //button.imageView!.clipsToBounds = true //button.imageView!.layer.cornerRadius = 60 button.clipsToBounds = true self.NavigationItem.rightBarButtonItems = [buttomItem,labelItem] } }) } else { self.NavigationItem.rightBarButtonItem = labelItem } print(" EL FRAME DEL BUTTON ES /(button.frame)") } else { labelbutton.setTitle("Login", for: UIControlState.normal) labelbutton.sizeToFit() self.NavigationItem.rightBarButtonItem = labelItem }


¿Lo que hice?

En mi aplicación, agregué una imagen de perfil en navigationBar en el elemento rightBarButton. antes de iOS 11 funcionaba bien y se mostraba correctamente, pero cuando se actualiza a iOS 11, cambia el comportamiento como golpe

Entonces, ¿agregué UIView en el elemento del botón derecho y configuré UIButton como subvista de UIView ? Como abajo,

Y establecí restricciones de altura y anchura de UIButton .

Y mi problema está resuelto. No olvide establecer el color de fondo de UIView como color claro .

NOTA: Si su botón no funciona, compruebe que UIView''s altura de su UIView''s podría ser 0 aquí, debe cambiar la altura de 0 a 44 o lo que desee. Y también haga clipToBound = true , ahora puede establecer la posición de su botón y funcionará bien.


A pesar de que iOS 11 usa Autolayout para la barra de navegación, es posible hacerlo funcionar estableciendo marcos tradicionalmente. Aquí está mi código que funciona para ios11 y ios10 o anterior:

func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem { let container = UIView(frame: rect) container.addSubview(view) view.frame = rect return UIBarButtonItem(customView: container) }

y así es como se compone el elemento de barra:

let btn = UIButton() btn.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal) btn.tintColor = tint btn.imageView?.contentMode = .scaleAspectFit let barItem = barItemWithView(view: btn, rect: CGRect(x: 0, y: 0, width: 22, height: 22)) return barItem


Bueno, el nuevo barButtonItem usa autolayout en lugar de tratar con marcos.

La imagen que estaba agregando al botón es más grande que el tamaño del botón en sí. Es por eso que el botón en sí se extendió al tamaño de la imagen. Debe cambiar el tamaño de la imagen para que coincida con el tamaño del botón necesario, antes de agregarlo al botón.


Cambiar el widthAnchor / heightAnchor solo funcionará en dispositivos iOS 11+. Para dispositivos iOS 10, debe seguir la forma clásica de cambiar manualmente los marcos. La cuestión es que ninguno de los dos enfoques funciona para ambas versiones, por lo que es absolutamente necesario alternar mediante programación dependiendo de la versión de tiempo de ejecución, como a continuación:

if #available(iOS 11.0, *) { button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true }else { var frame = button.frame frame.size.width = 32.0 frame.size.height = 32.0 button.frame = frame }


El código del objetivo C está obsoleto ahora. Pero para el usuario que tiene que construir / mantener proyectos de Objective C en iOS 11, la traducción de Swift (respuesta de Karoly Nyisztor) a Objective C es útil.

// UIView+Navbar.h #import <UIKit/UIKit.h> @interface UIView (Navbar) - (void)applyNavBarConstraints:(CGFloat)width height:(CGFloat)height; @end //---------- // UIView+Navbar.m #import "UIView+Navbar.h" @implementation UIView (Navbar) - (void)applyNavBarConstraints:(CGFloat)width height:(CGFloat)height { if (width == 0 || height == 0) { return; } NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:height]; NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:width]; [heightConstraint setActive:TRUE]; [widthConstraint setActive:TRUE]; } //---------- // Usage :- [button applyNavBarConstraints:33 height:33];


Escribí una pequeña extensión para establecer las restricciones en los elementos de la barra de navegación:

import UIKit extension UIView { func applyNavBarConstraints(size: (width: CGFloat, height: CGFloat)) { let widthConstraint = self.widthAnchor.constraint(equalToConstant: size.width) let heightConstraint = self.heightAnchor.constraint(equalToConstant: size.height) heightConstraint.isActive = true widthConstraint.isActive = true } } // Usage button.applyNavBarConstraints(size: (width: 33, height: 33))


He creado un elemento de botón de barra y luego lo agregué a la barra de navegación.

private var addItem: UIBarButtonItem = { let addImage = UIImage(named: "add") let addButton = UIButton(type: UIButton.ButtonType.custom) addButton.setBackgroundImage(addImage, for: UIControl.State()) addButton.frame = CGRect(x: 0, y: 0, width: (addImage?.size.width)!, height: (addImage?.size.height)!) let addItem = UIBarButtonItem(customView: addButton) return addItem }() private var contactsItem: UIBarButtonItem = { let contactsImage = UIImage(named: "contacts") let contactsButton = UIButton(type: UIButton.ButtonType.custom) contactsButton.setBackgroundImage(contactsImage, for: UIControl.State()) contactsButton.frame = CGRect(x: 0, y: 0, width: (contactsImage?.size.width)!, height: (contactsImage?.size.height)!) let contactsItem = UIBarButtonItem(customView: contactsButton) return contactsItem }()

En viewDidLoad ()

let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil) spacerBarButtonItem.width = 11 navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]

Aquí estoy teniendo la imagen de 28x28.


Hice esto en objetivo usando las siguientes líneas:

NSLayoutConstraint * widthConstraint = [customButton.widthAnchor constraintEqualToConstant:40]; NSLayoutConstraint * HeightConstraint =[customButton.heightAnchor constraintEqualToConstant:40]; [widthConstraint setActive:YES]; [HeightConstraint setActive:YES]; UIBarButtonItem* customBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customButton]; self.navigationItem.leftBarButtonItem = customBarButtonItem;

Gracias feliz codificación !!


Poner restricciones programáticamente funcionó para mí para los usuarios que ejecutan iOS 11.X. Sin embargo, el botón de la barra todavía se estiraba para los usuarios que ejecutaban iOS 10.X. Supongo que los revisores de AppStore ejecutaban iOS 11.X, por lo que no pudieron identificar mi problema, por lo que mi aplicación se preparó para la venta y se cargó.

Mi solución fue simplemente cambiar las dimensiones de mi imagen a 30x30 en otro software (la dimensión de la imagen anterior era 120x120).


También he tenido éxito al implementar intrinsicContentSize para devolver un tamaño apropiado para cualquier subclase de UIView personalizada que tenga la intención de usar como una vista personalizada.


Razón

El problema aparece porque desde ios 11 UIBarButtonItem usa autolayout en lugar de tratar con marcos.

Solución

Debería agregar una restricción de ancho para este botón de imagen si usa Xcode 9.

button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true

PD

button no es UIBarButtonItem , es UIButton dentro de UIBarButtonItem . Debe establecer la restricción no para UIBarButtonItem , sino para los elementos dentro de él.