导航栏 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 的图片。