Swift自定義導航欄返回按鈕
如何去除swift系統自帶的導航欄返回按鈕?可以自定義返回按鈕
在swift中,怎麼替換系統自帶的導航欄返回按鈕?比如說我要替換成一張返回按鈕圖片,點選返回到上一頁
首先,看一下系統自帶的導航欄返回按鈕的樣式
從上面我們可以看到,導航欄返回處左邊
是一個返回箭頭icon,右邊
是一個Back文字,這就構成了系統的導航欄返回按鈕,那麼現在,我不想使用系統的這個樣式,想自定義一個帶箭頭icon的按鈕,不需要文字,而且返回按鈕距離父superView左邊為15的距離,怎麼做呢?
首先,有人說,簡單呀,自定義UIBarButtonItem的customView就行了啊,然後會這樣寫
不符合要求的寫法
// 返回按鈕
let backButton = UIButton(type: .custom)
// 給按鈕設定返回箭頭圖片
backButton.setBackgroundImage(#imageLiteral(resourceName: "choose-photo_return"), for: .normal)
// 設定frame
backButton.frame = CGRect(x: 0, y: 13, width: 18, height: 18)
backButton.addTarget(self, action: #selector(back), for: .touchUpInside)
// 自定義導航欄的UIBarButtonItem型別的按鈕
let backView = UIBarButtonItem(customView: backButton)
// 返回按鈕設定成功
navigationItem.leftBarButtonItem = backView
但是,就這樣真的就可以了嗎?我們來看一下效果圖
咦?貌似達到要求了呀,好的,我們來列印一下backButton的frame,見下圖
有些人就鬱悶了,為什麼我設定的是 backButton.frame = CGRect(x: 0, y: 13, width: 18, height: 18)
也就是說,距離左邊的x為0, 但是怎麼run出來是20呢??這就牽扯到系統的預設設定問題,無論x的左邊你設定成多少,它預設就是20的邊距,也就是說,你只能設定frame的 y、 width、height, 但是設定x不起任何作用。好了, 打瞭解決關鍵問題的時刻了, 在導航欄中,UIBarButtonItem有一個這樣的初始化方法: public convenience init(barButtonSystemItem systemItem: UIBarButtonSystemItem, target: Any?, action: Selector?)
正確的寫法(標準)
// 返回按鈕
let backButton = UIButton(type: .custom)
// 給按鈕設定返回箭頭圖片
backButton.setBackgroundImage(#imageLiteral(resourceName: "choose-photo_return"), for: .normal)
// 設定frame
backButton.frame = CGRect(x: 200, y: 13, width: 18, height: 18)
backButton.addTarget(self, action: #selector(back), for: .touchUpInside)
// 自定義導航欄的UIBarButtonItem型別的按鈕
let backView = UIBarButtonItem(customView: backButton)
// 重要方法,用來調整自定義返回view距離左邊的距離
let barButtonItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
barButtonItem.width = -5
// 返回按鈕設定成功
navigationItem.leftBarButtonItems = [barButtonItem, backView]
接著我們看一下兩張效果圖
圖一
圖二
這樣, 我們就真正實現了自定導航欄返回按鈕的正確需要
注意事項,見如下程式碼註釋
- 注意點一
backButton.setBackgroundImage(#imageLiteral(resourceName: "choose-photo_return"), for: .normal)
不要寫成 backButton.setImage(#imageLiteral(resourceName: "choose-photo_return"), for: .normal)
, 因為前者是設定背景圖片,適應並鋪滿按鈕, 後者只是單純的設定圖片,但是,當frame的size變得很大的時候,setImage就會導致圖片在button中的位置有偏差,比如size大小為(width:200, height:200),這種情況下,返回按鈕距離左邊是15的距離,但是返回按鈕圖片距離左邊就不是15的距離了,就無法滿足需求!所以,為了保證不出錯,建議使用setBackgroundImage的形式。
- 注意點二
barButtonItem.width = -5
的意思是, backButton距離左邊為 20 - 5 的距離,因為系統自己預設的一定是 20 的距離, 所以我們要距離左邊越近, 設定的 barButtonItem.width
越小(負數), 比如現在我要backButton距離左邊的距離為 12, 那麼就應該設定成 barButtonItem.width = -8 (20 - 8 = 12), 所以一定要弄清楚它要表達的含義。
- 注意點三
navigationItem.leftBarButtonItems = [barButtonItem, backView]
後面陣列中的順序一定不能顛倒,必須按這個順序來, 否則設定不起任何作用。比如現在 我將其設定成 [backView, barButtonItem], 然後直接看列印的效果圖
總結, 這麼小的一個問題,卻花了不少的時間來完成這個問題的講解,是因為我覺得,在專案開發過程中,導航欄自定義返回按鈕是要經常用到的,並且一般而言,產品的需求很少說直接使用系統自帶的就可以,因此希望將這篇文章寫出來, 也算是完成以後在開發中再遇到類似的一個長期性的問題,以後完全可以按上面的按部就班!