1. 程式人生 > >Swift自定義導航欄返回按鈕

Swift自定義導航欄返回按鈕

如何去除swift系統自帶的導航欄返回按鈕?可以自定義返回按鈕

在swift中,怎麼替換系統自帶的導航欄返回按鈕?比如說我要替換成一張返回按鈕圖片,點選返回到上一頁

首先,看一下系統自帶的導航欄返回按鈕的樣式

test1

從上面我們可以看到,導航欄返回處左邊是一個返回箭頭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

但是,就這樣真的就可以了嗎?我們來看一下效果圖

test2

咦?貌似達到要求了呀,好的,我們來列印一下backButton的frame,見下圖

test3

有些人就鬱悶了,為什麼我設定的是 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]

接著我們看一下兩張效果圖

圖一

test4

圖二

test5

這樣, 我們就真正實現了自定導航欄返回按鈕的正確需要

注意事項,見如下程式碼註釋

  • 注意點一

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], 然後直接看列印的效果圖

test6

總結, 這麼小的一個問題,卻花了不少的時間來完成這個問題的講解,是因為我覺得,在專案開發過程中,導航欄自定義返回按鈕是要經常用到的,並且一般而言,產品的需求很少說直接使用系統自帶的就可以,因此希望將這篇文章寫出來, 也算是完成以後在開發中再遇到類似的一個長期性的問題,以後完全可以按上面的按部就班!