Swift 自定义导航栏后退按钮图像和文本
Swift Custom NavBar Back Button Image and Text
我需要在 Swift 项目中自定义后退按钮的外观。
这是我的资料:
这是我想要的:
我试过创建自己的 UIBarButtonItem,但我不知道如何让图像出现在文本旁边,而不是作为背景或文本的替代品。
let backButton = UIBarButtonItem(title: "Custom", style: .Plain, target: self, action: nil )
//backButton.image = UIImage(named: "imageName") //Replaces title
backButton.setBackgroundImage(UIImage(named: "imageName"), forState: .Normal, barMetrics: .Default) // Stretches image
navigationItem.setLeftBarButtonItem(backButton, animated: false)
对于后退按钮图像:
通过这个tutorial:(但对我不起作用)
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "imageName")
但是这个stack answer:(对我有用)
var backButtonImage = UIImage(named: "back-button-image")
backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 15, topCapHeight: 30)
UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
对于字体,假设您希望字体与整个导航栏相匹配:(当前正在使用)
if let font = UIFont(name: "Avenir-Book", size: 22) {
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
你可以这样做:
let yourBackImage = UIImage(named: "back_button_image")
self.navigationController?.navigationBar.backIndicatorImage = yourBackImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
self.navigationController?.navigationBar.backItem?.title = "Custom"
不过您的图片将只有一种颜色
Note: Please remember that the back button belongs to the the source ViewController and not to the destination ViewController. Thus, the modification needs to be done in the source VC, which is reflected to all the view in the navigation controller
代码片段:
let backImage = UIImage(named: "icon-back")
self.navigationController?.navigationBar.backIndicatorImage = backImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage
/*** If needed Assign Title Here ***/
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
swift 3
extension UIViewController {
func setBackButton(){
let yourBackImage = UIImage(named: "backbutton")
navigationController?.navigationBar.backIndicatorImage = yourBackImage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
}
}
swift 4
在我的例子中,我只需要按钮的图像,没有任何文本。我希望这对某人有用。
let imgBackArrow = UIImage(named: "back_arrow_32")
navigationController?.navigationBar.backIndicatorImage = imgBackArrow
navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBackArrow
navigationItem.leftItemsSupplementBackButton = true
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
对于iOS 12 你可以做到
func setNavigationBar() {
self.navigationItem.setHidesBackButton(true, animated:false)
//your custom view for back image with custom size
let view = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
if let imgBackArrow = UIImage(named: "icn_back_arrow") {
imageView.image = imgBackArrow
}
view.addSubview(imageView)
let backTap = UITapGestureRecognizer(target: self, action: #selector(backToMain))
view?.addGestureRecognizer(backTap)
let leftBarButtonItem = UIBarButtonItem(customView: view ?? UIView())
self.navigationItem.leftBarButtonItem = leftBarButtonItem
}
@objc func backToMain() {
self.navigationController?.popViewController(animated: true)
}
在带有图像和文本的导航栏中设置按钮非常困难。特别是在 iOS 11 中的 UIBarButtonItem 位置引入了新的令人头疼的问题之后:iOS 11 - UIBarButtonItem horizontal position
您可以制作带图像的按钮或带文本的按钮,但不能制作同时具有这两种按钮的按钮。我什至一起尝试了两个 UIBarButtonItems,一个带有图像,另一个带有文本 - 它看起来仍然一点也不好,而且它们的 UIStackView 不能轻易访问以进行修改。
没想到我找到了一个简单的解决方案:
1) 将按钮设计为Interface Builder 中的视图。在我的例子中,它位于目标 UIViewController 内,为简单起见可通过 IBOutlet 访问
2) 将图像的 Leading Space 约束设置为负数,您可能还想将视图的背景颜色设置为.clear。
3) 使用它:
@IBOutlet var backButtonView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(customView: self.backButtonView)
self.backButtonView.heightAnchor.constraint(equalToConstant: 44).isActive = true // if you set more than you'll get "Unable to simultaneously..."
self.backButtonView.widthAnchor.constraint(equalToConstant: 75).isActive = true
self.navigationItem.leftBarButtonItem = backButton
}
就是这样。无需为 iOS 10 使用带负间隔的技巧或为 iOS 11 使用带 imageInsets 的技巧(仅当您有图像且不适用于图像+文本时才有效,顺便说一句)。
只需将 backButton 替换为自定义 rightBarButtonItem
let backImage = UIImage(named: "BackBtn")?.withRenderingMode(.alwaysOriginal)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(popnav))
@objc func popnav() {
self.navigationController?.popViewController(animated: true)
}
我已经尝试了以上所有方法,并且都在不更改文本的情况下制作了自定义图像
唯一对我有用的是这个 answer
let backBTN = UIBarButtonItem(image: UIImage(named: "Back"),
style: .plain,
target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItem = backBTN
navigationController?.interactivePopGestureRecognizer?.delegate = self
Swift 4.2
添加此函数 ViewController
func addNavigationBarButton(imageName:String,direction:direction){
var image = UIImage(named: imageName)
image = image?.withRenderingMode(.alwaysOriginal)
switch direction {
case .left:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
case .right:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
}
}
@objc func goBack() {
navigationController?.popViewController(animated: true)
}
enum direction {
case right
case left
}
使用你应该在这里使用
viewDidLoad()
addNavigationBarButton(imageName: "ic_back", direction:.left)
用于设置自定义后退栏按钮并从后退栏按钮中删除文本,
仅来自故事板,没有任何编码。
结果:
这对我在 iOS 13 使用 swift 5 很有效。只需隐藏原来的后退按钮并添加一个带有操作的新导航左栏按钮项。
navigationItem.hidesBackButton = true
navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "backBtn"), style: .plain, target: self, action: #selector(back(sender:)))
@objc func back(sender: UIBarButtonItem) {
self.navigationController?.popViewController(animated:true)
}
以防万一有人需要用Swift5[更改所有Back
按钮颜色或字体 =21=]。 UIBarButtonItem.appearance().tintColor = .red
将此添加到 AppDelegate.swift 文件。
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UIBarButtonItem.appearance().tintColor = .white
UIBarButtonItem.appearance().setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: .red,
NSAttributedString.Key.font: UIFont(name: "font_name", size: 14)!
], for: .normal)
return true
}
}
我知道有人回答了。这里可以设置标题、图片和目标。
let view = UIView()
let button = UIButton(type: .system)
button.setImage(UIImage(named: "backArrow_theme"), for: .normal)
button.setTitle("Back to workflow", for: .normal)
button.addTarget(self, action: #selector(onBackButton(_:)), for: .touchUpInside)
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: -10)
button.sizeToFit()
view.addSubview(button)
view.frame = button.bounds
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: view)
您可以使用以下代码在 AppDelegate 中全局更改它:
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "custom-back")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "custom-back")
SWIFT 5
This works for me.
let backIcon = UIImage(named: "arrowRight")
self.navigationController?.navigationBar.backIndicatorImage = backIcon
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backIcon
navigationItem.backButtonTitle = ""
我需要在 Swift 项目中自定义后退按钮的外观。
这是我的资料:
这是我想要的:
我试过创建自己的 UIBarButtonItem,但我不知道如何让图像出现在文本旁边,而不是作为背景或文本的替代品。
let backButton = UIBarButtonItem(title: "Custom", style: .Plain, target: self, action: nil )
//backButton.image = UIImage(named: "imageName") //Replaces title
backButton.setBackgroundImage(UIImage(named: "imageName"), forState: .Normal, barMetrics: .Default) // Stretches image
navigationItem.setLeftBarButtonItem(backButton, animated: false)
对于后退按钮图像:
通过这个tutorial:(但对我不起作用)
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "imageName")
但是这个stack answer:(对我有用)
var backButtonImage = UIImage(named: "back-button-image") backButtonImage = backButtonImage?.stretchableImage(withLeftCapWidth: 15, topCapHeight: 30) UIBarButtonItem.appearance().setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
对于字体,假设您希望字体与整个导航栏相匹配:(当前正在使用)
if let font = UIFont(name: "Avenir-Book", size: 22) {
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
你可以这样做:
let yourBackImage = UIImage(named: "back_button_image")
self.navigationController?.navigationBar.backIndicatorImage = yourBackImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
self.navigationController?.navigationBar.backItem?.title = "Custom"
不过您的图片将只有一种颜色
Note: Please remember that the back button belongs to the the source ViewController and not to the destination ViewController. Thus, the modification needs to be done in the source VC, which is reflected to all the view in the navigation controller
代码片段:
let backImage = UIImage(named: "icon-back")
self.navigationController?.navigationBar.backIndicatorImage = backImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage
/*** If needed Assign Title Here ***/
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
swift 3
extension UIViewController {
func setBackButton(){
let yourBackImage = UIImage(named: "backbutton")
navigationController?.navigationBar.backIndicatorImage = yourBackImage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
}
}
swift 4
在我的例子中,我只需要按钮的图像,没有任何文本。我希望这对某人有用。
let imgBackArrow = UIImage(named: "back_arrow_32")
navigationController?.navigationBar.backIndicatorImage = imgBackArrow
navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBackArrow
navigationItem.leftItemsSupplementBackButton = true
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
对于iOS 12 你可以做到
func setNavigationBar() {
self.navigationItem.setHidesBackButton(true, animated:false)
//your custom view for back image with custom size
let view = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 10, y: 10, width: 20, height: 20))
if let imgBackArrow = UIImage(named: "icn_back_arrow") {
imageView.image = imgBackArrow
}
view.addSubview(imageView)
let backTap = UITapGestureRecognizer(target: self, action: #selector(backToMain))
view?.addGestureRecognizer(backTap)
let leftBarButtonItem = UIBarButtonItem(customView: view ?? UIView())
self.navigationItem.leftBarButtonItem = leftBarButtonItem
}
@objc func backToMain() {
self.navigationController?.popViewController(animated: true)
}
在带有图像和文本的导航栏中设置按钮非常困难。特别是在 iOS 11 中的 UIBarButtonItem 位置引入了新的令人头疼的问题之后:iOS 11 - UIBarButtonItem horizontal position
您可以制作带图像的按钮或带文本的按钮,但不能制作同时具有这两种按钮的按钮。我什至一起尝试了两个 UIBarButtonItems,一个带有图像,另一个带有文本 - 它看起来仍然一点也不好,而且它们的 UIStackView 不能轻易访问以进行修改。
没想到我找到了一个简单的解决方案:
1) 将按钮设计为Interface Builder 中的视图。在我的例子中,它位于目标 UIViewController 内,为简单起见可通过 IBOutlet 访问
2) 将图像的 Leading Space 约束设置为负数,您可能还想将视图的背景颜色设置为.clear。
3) 使用它:
@IBOutlet var backButtonView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(customView: self.backButtonView)
self.backButtonView.heightAnchor.constraint(equalToConstant: 44).isActive = true // if you set more than you'll get "Unable to simultaneously..."
self.backButtonView.widthAnchor.constraint(equalToConstant: 75).isActive = true
self.navigationItem.leftBarButtonItem = backButton
}
就是这样。无需为 iOS 10 使用带负间隔的技巧或为 iOS 11 使用带 imageInsets 的技巧(仅当您有图像且不适用于图像+文本时才有效,顺便说一句)。
只需将 backButton 替换为自定义 rightBarButtonItem
let backImage = UIImage(named: "BackBtn")?.withRenderingMode(.alwaysOriginal)
navigationItem.leftBarButtonItem = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(popnav))
@objc func popnav() {
self.navigationController?.popViewController(animated: true)
}
我已经尝试了以上所有方法,并且都在不更改文本的情况下制作了自定义图像 唯一对我有用的是这个 answer
let backBTN = UIBarButtonItem(image: UIImage(named: "Back"),
style: .plain,
target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItem = backBTN
navigationController?.interactivePopGestureRecognizer?.delegate = self
Swift 4.2
添加此函数 ViewController
func addNavigationBarButton(imageName:String,direction:direction){
var image = UIImage(named: imageName)
image = image?.withRenderingMode(.alwaysOriginal)
switch direction {
case .left:
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
case .right:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
}
}
@objc func goBack() {
navigationController?.popViewController(animated: true)
}
enum direction {
case right
case left
}
使用你应该在这里使用
viewDidLoad()
addNavigationBarButton(imageName: "ic_back", direction:.left)
用于设置自定义后退栏按钮并从后退栏按钮中删除文本, 仅来自故事板,没有任何编码。
结果:
这对我在 iOS 13 使用 swift 5 很有效。只需隐藏原来的后退按钮并添加一个带有操作的新导航左栏按钮项。
navigationItem.hidesBackButton = true
navigationItem.leftBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "backBtn"), style: .plain, target: self, action: #selector(back(sender:)))
@objc func back(sender: UIBarButtonItem) {
self.navigationController?.popViewController(animated:true)
}
以防万一有人需要用Swift5[更改所有Back
按钮颜色或字体 =21=]。 UIBarButtonItem.appearance().tintColor = .red
将此添加到 AppDelegate.swift 文件。
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UIBarButtonItem.appearance().tintColor = .white
UIBarButtonItem.appearance().setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: .red,
NSAttributedString.Key.font: UIFont(name: "font_name", size: 14)!
], for: .normal)
return true
}
}
我知道有人回答了。这里可以设置标题、图片和目标。
let view = UIView()
let button = UIButton(type: .system)
button.setImage(UIImage(named: "backArrow_theme"), for: .normal)
button.setTitle("Back to workflow", for: .normal)
button.addTarget(self, action: #selector(onBackButton(_:)), for: .touchUpInside)
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: -10)
button.sizeToFit()
view.addSubview(button)
view.frame = button.bounds
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: view)
您可以使用以下代码在 AppDelegate 中全局更改它:
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "custom-back")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "custom-back")
SWIFT 5
This works for me.
let backIcon = UIImage(named: "arrowRight")
self.navigationController?.navigationBar.backIndicatorImage = backIcon
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backIcon
navigationItem.backButtonTitle = ""