导航栏 rightbaritem 图像按钮错误 iOS 11
navigation bar rightbaritem image-button bug iOS 11
此代码在 ios10 中工作正常。我得到我的标签和一个图像按钮,它是用户照片配置文件,圆形圆形..好的。但是当 运行 xcode 9 ios11 模拟器时,我把它拉长了。按钮框架必须是 32x32,当检查 sim 卡并获取视图并告诉 xcode 描述视图时,我得到的输出为 170x32 或类似的东西。
这是我的代码。
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
}
原因
问题的出现是因为从ios 11 UIBarButtonItem
使用自动布局而不是处理框架。
解决方案
如果您使用 Xcode 9.
,则应为此图像按钮添加宽度限制
button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true
PS
button
不是UIBarButtonItem
,而是UIBarButtonItem
里面的UIButton
。您不应该为 UIBarButtonItem
设置约束,而应该为其中的元素设置约束。
嗯,新的 barButtonItem
使用自动布局而不是处理框架。
您添加到按钮的图像大于按钮本身的尺寸。这就是按钮本身被拉伸到图像大小的原因。在将图像添加到按钮之前,您必须调整图像大小以匹配所需按钮的大小。
感谢大家的贡献!你们是对的!对于 xcode9 ios11 你需要设置一个约束。
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
heightConstraint.isActive = true
widthConstraint.isActive = true
我写了一个小扩展来设置导航栏项目的约束:
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))
我还成功地实现了 intrinsicContentSize
到 return 适合我打算用作自定义视图的任何自定义 UIView 子类的大小。
即使 iOS 11 将自动布局用于导航栏,也可以使其在传统设置框架下工作。这是我为 ios11 和 ios10 或更早版本工作的代码:
func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem {
let container = UIView(frame: rect)
container.addSubview(view)
view.frame = rect
return UIBarButtonItem(customView: container)
}
下面是条形项的组成方式:
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
Objective C 代码现已过时。但是对于必须 build/maintain Objective C 在 iOS 中进行项目的用户,11 有以下来自 Swift 的翻译(
Karoly Nyisztor 的回答 ) 对 Objective C 很有帮助。
// 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];
我在 objective 中使用以下几行完成了此操作:
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;
谢谢编码愉快!!
我做了什么?
在我的应用程序中,我在 rightBarButton 项目的导航栏上添加了个人资料图片。在 iOS 11 之前它运行良好并且显示正常但是当更新到 iOS 11 然后改变行为就像打击
所以我在右键项中添加了UIView
并将UIButton
设置为UIView
的子视图?如下图,
并且我设置了UIButton
的高度和宽度限制。
我的问题已经解决了。不要忘记将 UIView
的背景颜色设置为 clear 颜色。
NOTE: If your button will not work then check your UIView's
height might be its 0 here you should change height 0 to 44 or whatever you want. And also do clipToBound = true
, Now you can set your button's position and It will be work well.
以编程方式设置约束对我对用户 运行 iOS 11.X 有效。 但是,对于用户来说,栏按钮仍然被拉长了 运行 iOS 10.X。 我猜 AppStore 的评论者是 运行 iOS 11.X 因此无法确定我的问题,所以我的应用已准备好出售并上传..
我的解决方案是在另一个软件中将图像的尺寸简单地更改为 30x30(之前的图像尺寸为 120x120)。
更改 widthAnchor
/heightAnchor
仅适用于 iOS 11+ 设备。对于 iOS 10 台设备,您需要采用手动更改帧的经典方法。问题是这两种方法中的 none 适用于两个版本,因此您绝对需要根据运行时版本以编程方式进行交替,如下所示:
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
}
我创建了一个栏按钮项,然后将其添加到导航栏上。
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
}()
在viewDidLoad()中
let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
spacerBarButtonItem.width = 11
navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]
这里我有一张 28x28 的图片。
此代码在 ios10 中工作正常。我得到我的标签和一个图像按钮,它是用户照片配置文件,圆形圆形..好的。但是当 运行 xcode 9 ios11 模拟器时,我把它拉长了。按钮框架必须是 32x32,当检查 sim 卡并获取视图并告诉 xcode 描述视图时,我得到的输出为 170x32 或类似的东西。
这是我的代码。
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
}
原因
问题的出现是因为从ios 11 UIBarButtonItem
使用自动布局而不是处理框架。
解决方案
如果您使用 Xcode 9.
,则应为此图像按钮添加宽度限制 button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true
PS
button
不是UIBarButtonItem
,而是UIBarButtonItem
里面的UIButton
。您不应该为 UIBarButtonItem
设置约束,而应该为其中的元素设置约束。
嗯,新的 barButtonItem
使用自动布局而不是处理框架。
您添加到按钮的图像大于按钮本身的尺寸。这就是按钮本身被拉伸到图像大小的原因。在将图像添加到按钮之前,您必须调整图像大小以匹配所需按钮的大小。
感谢大家的贡献!你们是对的!对于 xcode9 ios11 你需要设置一个约束。
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
heightConstraint.isActive = true
widthConstraint.isActive = true
我写了一个小扩展来设置导航栏项目的约束:
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))
我还成功地实现了 intrinsicContentSize
到 return 适合我打算用作自定义视图的任何自定义 UIView 子类的大小。
即使 iOS 11 将自动布局用于导航栏,也可以使其在传统设置框架下工作。这是我为 ios11 和 ios10 或更早版本工作的代码:
func barItemWithView(view: UIView, rect: CGRect) -> UIBarButtonItem {
let container = UIView(frame: rect)
container.addSubview(view)
view.frame = rect
return UIBarButtonItem(customView: container)
}
下面是条形项的组成方式:
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
Objective C 代码现已过时。但是对于必须 build/maintain Objective C 在 iOS 中进行项目的用户,11 有以下来自 Swift 的翻译( Karoly Nyisztor 的回答 ) 对 Objective C 很有帮助。
// 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];
我在 objective 中使用以下几行完成了此操作:
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;
谢谢编码愉快!!
我做了什么?
在我的应用程序中,我在 rightBarButton 项目的导航栏上添加了个人资料图片。在 iOS 11 之前它运行良好并且显示正常但是当更新到 iOS 11 然后改变行为就像打击
所以我在右键项中添加了UIView
并将UIButton
设置为UIView
的子视图?如下图,
并且我设置了UIButton
的高度和宽度限制。
我的问题已经解决了。不要忘记将 UIView
的背景颜色设置为 clear 颜色。
NOTE: If your button will not work then check your
UIView's
height might be its 0 here you should change height 0 to 44 or whatever you want. And also doclipToBound = true
, Now you can set your button's position and It will be work well.
以编程方式设置约束对我对用户 运行 iOS 11.X 有效。 但是,对于用户来说,栏按钮仍然被拉长了 运行 iOS 10.X。 我猜 AppStore 的评论者是 运行 iOS 11.X 因此无法确定我的问题,所以我的应用已准备好出售并上传..
我的解决方案是在另一个软件中将图像的尺寸简单地更改为 30x30(之前的图像尺寸为 120x120)。
更改 widthAnchor
/heightAnchor
仅适用于 iOS 11+ 设备。对于 iOS 10 台设备,您需要采用手动更改帧的经典方法。问题是这两种方法中的 none 适用于两个版本,因此您绝对需要根据运行时版本以编程方式进行交替,如下所示:
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
}
我创建了一个栏按钮项,然后将其添加到导航栏上。
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
}()
在viewDidLoad()中
let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
spacerBarButtonItem.width = 11
navigationItem.rightBarButtonItems = [addItem, spacerBarButtonItem, contactsItem]
这里我有一张 28x28 的图片。