101

此代码在 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

    }

在此处输入图像描述

4

12 回答 12

188

原因

出现问题是因为从 ios 11UIBarButtonItem开始使用自动布局而不是处理帧。

解决方案

如果你使用 Xcode 9,你应该为这个图像按钮添加宽度约束。

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

附言

button不是UIBarButtonItem,是UIButton里面UIBarButtonItem。您不应该为 设置约束UIBarButtonItem,而是为其中的元素设置约束。

于 2017-06-09T11:45:21.693 回答
53

感谢大家的贡献!你们是对的!对于 xcode9 ios11,您需要设置一个约束。

 let widthConstraint = button.widthAnchor.constraint(equalToConstant: 32)
 let heightConstraint = button.heightAnchor.constraint(equalToConstant: 32)
 heightConstraint.isActive = true
 widthConstraint.isActive = true
于 2017-06-15T22:05:49.667 回答
18

Objective C 代码现在已经过时了。但是对于必须在 iOS 11 中构建/维护 Objective C 项目的用户来说,从 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];
于 2017-09-21T06:11:49.887 回答
18

好吧,新的barButtonItem使用自动布局而不是处理帧。

您添加到按钮的图像大于按钮本身的大小。这就是按钮本身被拉伸到图像大小的原因。在将图像添加到按钮之前,您必须调整图像大小以匹配所需按钮的大小。

于 2017-06-09T12:27:06.630 回答
14

我写了一个小扩展来设置导航栏项目的约束:

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))
于 2017-09-19T17:08:09.960 回答
12

我使用以下几行客观地做到了这一点:

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;

谢谢快乐编码!

于 2017-09-29T11:49:47.593 回答
7

我做了什么?

在我的应用程序中,我在 rightBarButton 项的导航栏上添加了个人资料图片。在 iOS 11 之前它运行良好并且显示正常,但是当更新到 iOS 11 时会改变行为,比如打击

在此处输入图像描述

所以我添加UIView了右键项目并设置UIButton为子视图UIView?如下图,

在此处输入图像描述

我设置了高度和宽度约束UIButton

在此处输入图像描述 在此处输入图像描述

我的问题解决了。不要忘记将UIView背景颜色设置为清晰的颜色。

注意:如果您的按钮不起作用,那么检查您的UIView's高度可能是它的0 ,您应该将高度0更改为44或任何您想要的。还有clipToBound = true,现在你可以设置按钮的位置,它会很好用。

于 2017-10-06T10:02:14.800 回答
5

更改widthAnchor/heightAnchor仅适用于 iOS 11+ 设备。对于 iOS 10 设备,您需要采用手动更改框架的经典方式。问题是这两种方法都不适用于两个版本,因此您绝对需要根据运行时版本以编程方式交替,如下所示:

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
}
于 2017-12-18T14:26:54.593 回答
3

对于运行 iOS 11.X 的用户,以编程方式设置约束对我有用。但是,对于运行 iOS 10.X 的用户,栏按钮仍然是拉伸的。我猜 AppStore 审阅者正在运行 iOS 11.X,因此无法识别我的问题,所以我的应用程序已准备好出售并上传..

我的解决方案是在另一个软件中简单地将我的图像尺寸更改为 30x30(之前的图像尺寸为 120x120)。

于 2017-10-22T07:06:16.987 回答
3

即使 iOS 11 使用 Autolayout 作为导航栏,它也可以使用传统的设置框架。这是我适用于 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
于 2017-09-20T07:31:08.887 回答
0

通过实现intrinsicContentSize为我打算用作 customView 的任何自定义 UIView 子类返回适当的大小,我也取得了成功。

于 2017-09-19T23:13:36.517 回答
0

我创建了一个栏按钮项,然后将其添加到导航栏。

    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 的图像。

于 2018-09-17T14:39:45.830 回答