如何在Swift中以编程方式创建一个“返回”UIBarButton项目?

24

我可以使用以下代码创建一个可编程返回的UIBarButton项:

    func backAction() -> Void {        
        self.navigationController?.popViewControllerAnimated(true)
    }
override func viewDidLoad() {
        super.viewDidLoad()
    let backButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.Plain, target: self, action: "backAction")

        self.navigationItem.leftBarButtonItem = backButton
    }
问题在于后退按钮没有向左箭头: enter image description here 有没有办法让它看起来像一个普通的带箭头的后退按钮,如下所示:enter image description here 我还想知道是否有一种方法可以使按钮标题名称成为上一个视图控制器的标题,如果可能的话。
谢谢。

你是如何导航到可见的控制器的?是使用presentViewController还是pushViewController? - sKhan
它是通过“模态呈现”而不是通过导航控制器实现的。 - Rami Ammoun
7个回答

48
使用UIButton和图片的代码可以将其作为UIBarButtonItem的自定义视图添加:

以下是该代码

override func viewDidLoad() {
    super.viewDidLoad()
    var backbutton = UIButton(type: .Custom)
    backbutton.setImage(UIImage(named: "BackButton.png"), forState: .Normal) // Image can be downloaded from here below link 
    backbutton.setTitle("Back", forState: .Normal)
    backbutton.setTitleColor(backbutton.tintColor, forState: .Normal) // You can change the TitleColor
    backbutton.addTarget(self, action: "backAction", forControlEvents: .TouchUpInside)

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backbutton)
}

func backAction() -> Void {        
   self.navigationController?.popViewControllerAnimated(true)
}

BackButton.png 下载链接

要设置返回按钮的标题为前一个视图控制器的标题,您需要在呈现控制器时将标题作为字符串传递,将上述代码进行更改。

var titleStrFromPreviousController: String // This value has to be set from previous controller while presenting modal controller
backbutton.setTitle(titleStrFromPreviousController, forState: .Normal)

这可能会有所帮助。

Swift 3

override func viewDidLoad() {
    super.viewDidLoad()

    addBackButton()
}

func addBackButton() {
    let backButton = UIButton(type: .custom)
    backButton.setImage(UIImage(named: "BackButton.png"), for: .normal) // Image can be downloaded from here below link
    backButton.setTitle("Back", for: .normal)
    backButton.setTitleColor(backButton.tintColor, for: .normal) // You can change the TitleColor
    backButton.addTarget(self, action: #selector(self.backAction(_:)), for: .touchUpInside)

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
}

@IBAction func backAction(_ sender: UIButton) {
   let _ = self.navigationController?.popViewController(animated: true)
}

1
你应该遵循 https://developer.apple.com/ios/human-interface-guidelines/icons-and-images/custom-icons/ 中的图片大小。 - sKhan
在 Swift 中添加 backButton.frame = CGRect(x: 0, y: 0, width: 100, height: 25) 或类似的内容。 - djdance

13

更新至Swift 4.2 - 感谢sam bing和silentbeep。

对一些颜色和操作选择器进行了修改。

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .blue
        self.navigationItem.title = title
        self.navigationController?.navigationBar.barTintColor = .white
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: makeBackButton())
    }

    func makeBackButton() -> UIButton {
        let backButtonImage = UIImage(named: "backbutton")?.withRenderingMode(.alwaysTemplate)
        let backButton = UIButton(type: .custom)
        backButton.setImage(backButtonImage, for: .normal)
        backButton.tintColor = .blue
        backButton.setTitle("  Back", for: .normal)
        backButton.setTitleColor(.blue, for: .normal)
        backButton.addTarget(self, action: #selector(self.backButtonPressed), for: .touchUpInside)
        return backButton
    }

    @objc func backButtonPressed() {
        dismiss(animated: true, completion: nil)
//        navigationController?.popViewController(animated: true)
    }

通过这个解决方案,您将获得自定义按钮,但是您将失去从左向右拖动返回到上一个视图控制器的功能。唯一的返回方式将是按下按钮。 - christostsang

4
您可以通过将视图嵌入导航控制器来实现此操作。 以下是演示如何执行此操作的图片:navigationController 希望对您有所帮助:D

默认情况下应该显示。 - Pixele9
1
如果你想要得到返回按钮,你需要呈现或推到那个导航控制器。 - Braham Youssef

4

为了便于未来的搜索,我想补充一下,您可以使用以下代码来使用默认图标:

override public func viewDidLoad() {
    // create chevron image
    let config = UIImage.SymbolConfiguration(pointSize: 25.0, weight: .medium, scale: .medium)
    let image = UIImage(systemName: "chevron.left", withConfiguration: config)

    // create back button
    let backButton = UIButton(type: .custom)
    backButton.addTarget(self, action: #selector(self.close(_:)), for: .touchUpInside)
    backButton.setImage(image, for: .normal)
    backButton.setTitle("Back", for: .normal)
    backButton.setTitleColor(backButton.tintColor, for: .normal)
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
}

@IBAction func close(_ sender: UIButton) {
    self.navigationController?.dismiss(animated: true, completion: nil)
}

1
第一个答案非常好,但是图像有点太大了,因此请使用预览并将其缩小到宽度:13和高度:22,同时将其渲染模式设置为 .alwaysTemplate ,并将 UIButton 的色调更改为白色,同时在字符串“ Back”之前添加两个空格。这将产生与导航栏返回按钮相似的东西,图像在大小和位置方面可能更好。
编辑后的代码:
     func addBackButton() {


            let backButtonImage = UIImage(named: "BackButton.png")?.withRenderingMode(.alwaysTemplate)

            let backButton = UIButton(type: .custom)
            backButton.setImage(backButtonImage, for: .normal) 
            backButton.tintColor = .white
            backButton.setTitle("  Back", for: .normal)
            backButton.setTitleColor(.white, for: .normal)
            backButton.addTarget(self, action: #selector(self.backAction(_:)), for: .touchUpInside)

            self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)


}

1

我按照选定答案的最后一行修改了代码,现在它可以正常工作了。

override func viewDidLoad() {
    super.viewDidLoad()

    addBackButton()
}

func addBackButton() {
    let backButton = UIButton(type: .custom)
    backButton.setImage(UIImage(named: "BackButton.png"), for: .normal) // Image can be downloaded from here below link
    backButton.setTitle("Back", for: .normal)
    backButton.setTitleColor(backButton.tintColor, for: .normal) // You can change the TitleColor
    backButton.addTarget(self, action: #selector(self.backAction(_:)), for: .touchUpInside)

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
}

@IBAction func backAction(_ sender: UIButton) {
   let _ = self.dismiss(animated: true, completion: nil)
}

0

Swift 5

override func viewDidLoad() {
            super.viewDidLoad()
            let backbutton = UIButton(type: .custom)
            backbutton.setImage(UIImage(named: "BackButton.png"), for: .normal) // Image can be downloaded from here below link
            backbutton.setTitle("Back", for: .normal)
            backbutton.setTitleColor(backbutton.tintColor, for: .normal) // You can change the TitleColor
            backbutton.addTarget(self, action: Selector(("backAction")), for: .touchUpInside)
    
            self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backbutton)
        }
    
        func backAction() -> Void {
            self.navigationController?.popViewController(animated: true)
        }

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