Dieser Code funktioniert in ios10. Ich bekomme mein Etikett und einen Bildknopf, der das Benutzerfotoprofil ist, kreisrund .. ok. aber wenn ich xcode 9 ios11 simulator laufen lasse, bekomme ich es ausgestreckt. Der Schaltflächenrahmen muss 32x32 sein, wenn Sie auf der Sim nachsehen und die Ansicht abrufen und xcode angeben, um die Ansicht zu beschreiben. Ich erhalte die Ausgabe als 170x32 oder so ähnlich.
hier ist mein 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
}
Grund
Das Problem tritt auf, weil ab ios 11 UIBarButtonItem
Autolayout verwendet, anstatt sich mit Frames zu befassen.
Lösung
Wenn Sie Xcode 9 verwenden, sollten Sie für diese Bildschaltfläche eine Breitenbeschränkung hinzufügen.
button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true
PS
button
ist nicht UIBarButtonItem
, sondern UIButton
in UIBarButtonItem
. Sie sollten die Einschränkung nicht für UIBarButtonItem
, sondern für darin enthaltene Elemente festlegen.
Vielen Dank für Ihren Beitrag! ihr seid richtig !. Für xcode9 ios11 müssen Sie eine Einschränkung setzen.
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
heightConstraint.isActive = true
widthConstraint.isActive = true
Nun, das neue barButtonItem
verwendet Autolayout anstelle von Frames.
Das Bild, das Sie der Schaltfläche hinzugefügt haben, ist größer als die Schaltfläche selbst. Aus diesem Grund wurde der Knopf selbst auf die Größe des Bildes gedehnt. Sie müssen die Größe des Bildes anpassen, um es an die Größe der gewünschten Schaltfläche anzupassen, bevor Sie es der Schaltfläche hinzufügen.
Der objektive C-Code ist jetzt veraltet. Aber für den Benutzer, der Objective C-Projekte in iOS 11 erstellen/warten muss, ist folgende Übersetzung von Swift (Karoly Nyisztor answer) zu Objective C hilfreich.
// 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];
Ich habe eine winzige Erweiterung zum Festlegen der Einschränkungen für Navigationsleistenelemente geschrieben:
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))
Ich habe dies objektiv mit folgenden Zeilen gemacht:
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;
Vielen Dank Happy Coding!
Was ich getan habe?
In meiner App habe ich ein Profilbild in der Navigationsleiste unter "rightBarButton" hinzugefügt. vor iOS 11 funktionierte es gut und wurde korrekt angezeigt, aber wenn es auf iOS 11 aktualisiert wurde, ändert sich das Verhalten wie Schlag
Also habe ich UIView
im rechten Schaltflächenelement hinzugefügt und UIButton
als Unteransicht von UIView
festgelegt? Wie unten,
Und ich setze Höhen- und Breitenbeschränkungen von UIButton
.
Und mein Problem ist gelöst. Vergessen Sie nicht, die Hintergrundfarbe von UIView
als klare Farbe festzulegen.
HINWEIS: Wenn Ihre Schaltfläche nicht funktioniert, überprüfen Sie Ihre
UIView's
height könnte sein 0 hier sollten Sie die Höhe 0 auf ändern 44 oder was auch immer Sie wollen. Und mache auchclipToBound = true
, Jetzt können Sie die Position Ihrer Taste festlegen und es wird gut funktionieren.
Das Ändern von widthAnchor
/heightAnchor
funktioniert nur auf Geräten mit iOS 11+. Für iOS 10-Geräte müssen Sie die klassischen Methoden zum manuellen Ändern der Frames anwenden. Die Sache ist, dass keiner der beiden Ansätze für beide Versionen funktioniert. Sie müssen also abhängig von der Laufzeitversion wie folgt programmgesteuert abwechseln:
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
}
Obwohl iOS 11 Autolayout für die Navigationsleiste verwendet, ist es möglich, das herkömmliche Einstellen von Frames zu ermöglichen. Hier ist mein Code für ios11 und ios10 oder älter:
func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem {
let container = UIView(frame: rect)
container.addSubview(view)
view.frame = rect
return UIBarButtonItem(customView: container)
}
und so setzt sich das Barelement zusammen:
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
Das programmgesteuerte Setzen von Einschränkungen hat bei mir für Benutzer mit iOS 11.X funktioniert. Allerdings war die Leistenschaltfläche für Benutzer mit iOS 10.X weiterhin gedehnt. Ich denke, die AppStore-Rezensenten haben iOS 11.X ausgeführt. Daher konnte ich mein Problem nicht identifizieren, sodass meine App für den Verkauf vorbereitet und hochgeladen wurde ..
Meine Lösung bestand darin, die Abmessungen meines Bildes in einer anderen Software einfach auf 30 x 30 zu ändern (vorherige Bildgröße war 120 x 120).
Ich habe ein Leistenschaltflächenelement erstellt und es dann der Navigationsleiste hinzugefügt.
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
}()
In viewDidLoad ()
let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
spacerBarButtonItem.width = 11
navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]
Hier habe ich das Bild von 28x28.
Ich hatte auch Erfolg mit der Implementierung von intrinsicContentSize
, um eine angemessene Größe für jede benutzerdefinierte UIView-Unterklasse zurückzugeben, die ich als customView verwenden möchte.