Ce code fonctionne bien dans ios10. Je reçois mon étiquette et un bouton d’image qui correspond au profil de la photo de l’utilisateur, circulaire. ok. mais lorsque je lance xcode 9 ios11 simulator, je l’ai étouffé. le cadre du bouton doit être 32x32, lors de la vérification de la sim et de l'affichage de la vue et de l'indication de xcode pour décrire la vue, la sortie est 170x32 ou quelque chose comme ça.
heres mon code.
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
}
Raison
Le problème apparaît car, à partir de ios 11, UIBarButtonItem
utilise autolayout au lieu de traiter les images.
Solution
Vous devez ajouter une contrainte de largeur pour ce bouton image si vous utilisez Xcode 9.
button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true
PS
button
n'est pas UIBarButtonItem
, c'est UIButton
à l'intérieur de UIBarButtonItem
. Vous ne devez pas définir la contrainte pour UIBarButtonItem
, mais pour les éléments qu’elle contient.
Merci à tous pour votre contribution! vous avez raison! pour xcode9 ios11, vous devez appliquer une contrainte.
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
heightConstraint.isActive = true
widthConstraint.isActive = true
Eh bien, la nouvelle barButtonItem
utilise autolayout au lieu de traiter avec des cadres.
L'image que vous ajoutiez au bouton est plus grande que la taille du bouton lui-même. C'est pourquoi le bouton lui-même s'est étiré à la taille de l'image. Vous devez redimensionner l'image pour qu'elle corresponde à la taille du bouton souhaité avant de l'ajouter au bouton.
Le code Objective C est obsolète maintenant. Mais pour l'utilisateur qui doit construire/maintenir des projets Objective C dans iOS 11, la traduction suivante de Swift (réponse de Karoly Nyisztor) à Objective C est utile.
// 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];
J'ai écrit une petite extension pour définir les contraintes sur les éléments de la barre de navigation:
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))
J'ai fait ceci en objectif en utilisant les lignes suivantes:
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;
Merci codage heureux !!
Ce que j'ai fait?
Dans mon application, j'ai ajouté une image de profil sur navigationBar à l'élément rightBarButton. avant iOS 11, il fonctionnait bien et s’affiche correctement, mais lorsqu’il est mis à jour vers iOS 11, le comportement change comme un coup dur.
J'ai donc ajouté UIView
dans l'élément du bouton de droite et défini UIButton
comme sous-vue de UIView
? Comme ci-dessous,
Et je règle les contraintes de hauteur et de largeur de UIButton
.
Et mon problème est résolu. N'oubliez pas de définir la couleur d'arrière-plan de UIView
comme claire .
REMARQUE: Si votre bouton ne fonctionnera pas, vérifiez que votre
UIView's
hauteur correspond à sa 0 ici vous devez changer la hauteur 0 en 44 ou ce que vous voulez. Et aussi, faitesclipToBound = true
, vous pouvez maintenant régler la position de votre bouton et cela fonctionnera bien.
Changer la widthAnchor
/heightAnchor
ne fonctionnera que sur les appareils iOS 11+. Pour les appareils iOS 10, vous devez utiliser la méthode classique de modification manuelle des images. Le fait est qu'aucune des deux approches ne fonctionne pour les deux versions, vous devez donc impérativement alterner par programme en fonction de la version d'exécution, comme ci-dessous:
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
}
Même si iOS 11 utilise Autolayout pour la barre de navigation, il est possible de le faire fonctionner traditionnellement en définissant des cadres. Voici mon code fonctionnant pour ios11 et ios10 ou plus ancien:
func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem {
let container = UIView(frame: rect)
container.addSubview(view)
view.frame = rect
return UIBarButtonItem(customView: container)
}
et voici comment se compose l'article de barre:
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
Mettre les contraintes par programme a fonctionné pour moi pour les utilisateurs de iOS 11.X. Cependant, le bouton de barre était toujours étendu pour les utilisateurs de iOS 10.X. Je suppose que les relecteurs de l'AppStore fonctionnaient sous iOS 11.X, donc je ne pouvais pas identifier mon problème, donc mon application était prête pour la vente et téléchargée. ..
Ma solution consistait simplement à modifier les dimensions de mon image en 30x30 dans un autre logiciel (les dimensions de l'image précédente étaient 120x120).
J'ai créé un élément de bouton de barre, puis je l'ai ajouté à la barre de navigation.
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
}()
Dans viewDidLoad ()
let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
spacerBarButtonItem.width = 11
navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]
Ici, j'ai l'image de 28x28.
J'ai également eu du succès en implémentant intrinsicContentSize
pour renvoyer une taille appropriée pour toute sous-classe UIView personnalisée que je compte utiliser comme customView.