如何使用Swift设置导航栏按钮图标?

71

我试图为一个条形按钮设置图片,我有一张分辨率为30*30的图片:

这里输入图片描述

但当我将这张图片赋给条形按钮时,它看起来像这样:

这里输入图片描述

我是这样赋值的:

这里输入图片描述

如果我按照这个问题中的代码方式做,即通过制作IBOutlet并以编程方式设置图像,则可以尝试以下方式:

 // Outlet for bar button
 @IBOutlet weak var fbButton: UIBarButtonItem!

// Set Image for bar button
var backImg: UIImage = UIImage(named: "fb.png")!
fbButton.setBackgroundImage(backImg, forState: .Normal, barMetrics: .Default)

但是这没有任何变化,

有人可以告诉我我做错了什么吗?

或者有更好的方法来做这个吗?

16个回答

110

我用以下代码以编程方式实现了这个:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //create a new button
        let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
        //set image for button
        button.setImage(UIImage(named: "fb.png"), forState: UIControlState.Normal)
        //add function for button
        button.addTarget(self, action: "fbButtonPressed", forControlEvents: UIControlEvents.TouchUpInside)
        //set frame
        button.frame = CGRectMake(0, 0, 53, 31)

        let barButton = UIBarButtonItem(customView: button)
        //assign button to navigationbar
        self.navigationItem.rightBarButtonItem = barButton
    }

    //This method will call when you press button.
    func fbButtonPressed() {

        println("Share to fb")
    }
}

结果会是这样:

enter image description here

同样的方法,您也可以将按钮设置在左侧:

self.navigationItem.leftBarButtonItem = barButton

结果将会是:

在此输入图片描述

如果您想要与导航控制器使用默认返回按钮时相同的转场效果,那么可以使用以下代码来实现自定义返回按钮:

func backButtonPressed(sender:UIButton) {
    navigationController?.popViewControllerAnimated(true)
}

对于 Swift 3.0:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //create a new button
        let button = UIButton.init(type: .custom)
        //set image for button
        button.setImage(UIImage(named: "fb.png"), for: UIControlState.normal)
        //add function for button
        button.addTarget(self, action: #selector(ViewController.fbButtonPressed), for: UIControlEvents.touchUpInside)
        //set frame
        button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)

        let barButton = UIBarButtonItem(customView: button)
        //assign button to navigationbar
        self.navigationItem.rightBarButtonItem = barButton
    }

    //This method will call when you press button.
    func fbButtonPressed() {

        print("Share to fb")
    }
}

对于 Swift 4.0:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //create a new button
        let button = UIButton(type: .custom)
        //set image for button
        button.setImage(UIImage(named: "fb.png"), for: .normal)
        //add function for button
        button.addTarget(self, action: #selector(fbButtonPressed), for: .touchUpInside)
        //set frame
        button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)

        let barButton = UIBarButtonItem(customView: button)
        //assign button to navigationbar
        self.navigationItem.rightBarButtonItem = barButton
    }

    //This method will call when you press button.
    @objc func fbButtonPressed() {

        print("Share to fb")
    }
}

8
非常好的解决方案。我认为你不需要把它转换成UIButton let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton。实际上,在Swift 2.1中,我们有这个: let button: UIButton = UIButton(type: UIButtonType.Custom) - Keith Holliday
7
对于Swift 4,您还需要添加宽度和高度约束锚点到 button,并将其 translatesAutoresizingMaskIntoConstraints 设置为 false。例如:button.widthAnchor.constraint(equalToConstant: 53).isActive = true button.heightAnchor.constraint(equalToConstant: 51).isActive = true - kbunarjo

50

一个简单的解决方案可能是以下内容

barButtonItem.image = UIImage(named: "image")

然后进入Assets.xcassets,选择图像,进入Attribute Inspector,并选择“Original Image”作为Reder选项。


有时候答案比我们想象的要简单。之前,我创建了一个新的UIBarButtonItem,使用我想要更改的图像进行初始化,并将其分配给当前的UIBarButtonItem。显然,您不必这样做。只需将当前UIBarButtonItem的图像属性设置为我想要更改的图像即可。 ‍♂️。谢谢! - yohannes
3
另外,如果图像不在资产目录中,您可以使用UIImage扩展.withRenderingMode(.alwaysOriginal)来实现相同的效果。UIImage(named: "image").withRenderingMode(.alwaysOriginal) - Mike
1
这是这个问题最简单的答案。它应该被接受,而不是上面过于复杂的答案。 - Mauricio Chirino

21
与被接受的解决方案类似,但您可以替换

let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton

使用

let button = UIButton()

以下是完整的解决方案,希望您喜欢(这个方案比被接受的方案更简洁):
let button = UIButton()
button.frame = CGRectMake(0, 0, 51, 31) //won't work if you don't set frame
button.setImage(UIImage(named: "fb"), forState: .Normal)
button.addTarget(self, action: Selector("fbButtonPressed"), forControlEvents: .TouchUpInside)

let barButton = UIBarButtonItem()
barButton.customView = button
self.navigationItem.rightBarButtonItem = barButton

在 fbButtonPressed 的末尾添加一个冒号。 - Abdul Waheed
@AbdulWaheed 这是不正确的,因为它没有接受任何参数。 - jungledev
1
你太棒了 Heidi! - Dew Time
3
对于Swift 4,您还需要为“button”添加宽度和高度约束锚点,并将其translatesAutoresizingMaskIntoConstraints设置为false。例如:button.widthAnchor.constriant(equalToConstant: 51).isActive = true button.heightAnchor.constraint(equalToConstant: 31).isActive = true - kbunarjo

15

这是一个对UIBarButtonItem的简单扩展:

extension UIBarButtonItem {
    class func itemWith(colorfulImage: UIImage?, target: AnyObject, action: Selector) -> UIBarButtonItem {
        let button = UIButton(type: .custom)
        button.setImage(colorfulImage, for: .normal)
        button.frame = CGRect(x: 0.0, y: 0.0, width: 44.0, height: 44.0)
        button.addTarget(target, action: action, for: .touchUpInside)

        let barButtonItem = UIBarButtonItem(customView: button)
        return barButtonItem
    }
}

7
对于 Swift 4,您还需要为 button 添加宽度和高度约束锚点,并将其 translatesAutoresizingMaskIntoConstraints 属性设置为 false。例如:button.widthAnchor.constraint(equalToConstant: 44).isActive = truebutton.heightAnchor.constraint(equalToConstant: 44).isActive = true - kbunarjo

12

仅需要两行代码

Swift 3.0

let closeButtonImage = UIImage(named: "ic_close_white")
        navigationItem.rightBarButtonItem = UIBarButtonItem(image: closeButtonImage, style: .plain, target: self, action:  #selector(ResetPasswordViewController.barButtonDidTap(_:)))

func barButtonDidTap(_ sender: UIBarButtonItem) 
{

}

完美!简短!并且具有适当的UIBarButton色调! - Phuah Yee Keat

11

我正在使用最新的Swift (2.1),而答案(Dharmesh Kheni和jungledev)对我不起作用。图片颜色不正确(在IB中设置为蓝色,在UIButton中直接设置为黑色)。原来我可以用以下代码创建相同的栏目:

let barButton = UIBarButtonItem(image: UIImage(named: "menu"), landscapeImagePhone: nil, style: .Done, target: self, action: #selector(revealBackClicked))
self.navigationItem.leftBarButtonItem = barButton

6
您可以使用以下代码来创建多个带有自定义图像的操作按钮:
self.navigationItem.leftBarButtonItem = nil

let button = UIButton(type: .custom)
button.setImage(UIImage (named: "ChatTab"), for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)

let button2 = UIButton(type: .custom)
button2.setImage(UIImage (named: "ActivityTab"), for: .normal)
button2.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)

let barButtonItem2 = UIBarButtonItem(customView: button2)
self.navigationItem.rightBarButtonItems = [barButtonItem, barButtonItem2]

Result will be this:

enter image description here


self.navigationItem.leftBarButtonItem = nil 为什么要写这行代码? - Mohmmad S
他一定是得到返回按鈕 <Back。也許他不想要它。 - Yash Bedi

5
你的问题是由于图标制作方式不符合苹果的自定义选项卡栏图标规范导致的:
要设计自定义栏图标,请遵循以下准则:
  • 使用纯白色和适当的 alpha 透明度。
  • 不包括阴影。
  • 使用抗锯齿技术。
(来自 指南。)
可能看起来像这样的东西。你可以在大多数免费选项卡栏图标网站上找到这样的图标。

Button example


谢谢您的回复,您能否给我提供一个可以下载这种图片的网站? - Dharmesh Kheni

5

像下面这样初始化barbuttonItem:

let pauseButton = UIBarButtonItem(image: UIImage(named: "big"),
                                  style: .plain,
                                  target: self,
                                  action: #selector(PlaybackViewController.pause))

3

Swift 4.

@IBOutlet weak var settingBarBtn: UIBarButtonItem! {
    didSet {
        let imageSetting = UIImageView(image: UIImage(named: "settings"))
        imageSetting.image = imageSetting.image!.withRenderingMode(.alwaysOriginal)
        imageSetting.tintColor = UIColor.clear
        settingBarBtn.image = imageSetting.image
    }
}

如何使用它? - Dipen Chudasama
在视图控制器中使用如下代码:@IBOutlet weak var profileBarButton: UIBarButtonItem! { didSet { let imageSetting = UIImageView(image: UIImage(named: "staticUserProfile")) imageSetting.image = imageSetting.image!.withRenderingMode(.alwaysOriginal) imageSetting.tintColor = UIColor.clear profileBarButton.image = imageSetting.image } } - Egzon P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接