2014-10-09 70 views
22

有人可以幫助我認識一個水龍頭當用戶點擊標題導航欄認識點擊導航欄標題

我想識別這個水龍頭,然後動畫tableHeaderView出現。可能滑動TableView。

想法是,用戶可以選擇一個快速選項(從tableViewHeader)重新填充TableView。

但是我無法識別任何水龍頭。

我正在使用Swift。

謝謝。

回答

38

UINavigationBar不公開其內部層次結構。沒有支持的方式來獲得顯示標題的UILabel的引用。

您可以通過「手動」(通過搜索其subviews)在其視圖層次結構中紮根,但由於視圖層次結構是私有的,因此可能會在未來的iOS版本中停止工作。

一種解決方法是創建一個UILabel並將其設置爲您的視圖控制器的navigationItem.titleView。您可以根據默認標籤的樣式進行匹配,這可能會在不同版本的iOS中更改。

這就是說,它是很容易設置:

override func didMove(toParentViewController parent: UIViewController?) { 
    super.didMove(toParentViewController: parent) 

    if parent != nil && self.navigationItem.titleView == nil { 
     initNavigationItemTitleView() 
    } 
} 

private func initNavigationItemTitleView() { 
    let titleView = UILabel() 
    titleView.text = "Hello World" 
    titleView.font = UIFont(name: "HelveticaNeue-Medium", size: 17) 
    let width = titleView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)).width 
    titleView.frame = CGRect(origin:CGPoint.zero, size:CGSize(width: width, height: 500)) 
    self.navigationItem.titleView = titleView 

    let recognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewController.titleWasTapped)) 
    titleView.userInteractionEnabled = true 
    titleView.addGestureRecognizer(recognizer) 
} 

@objc private func titleWasTapped() { 
    NSLog("Hello, titleWasTapped!") 
} 

我(使用sizeThatFits:)標籤的大小設置爲它的自然寬度,但我高度設置爲500。導航欄將保持寬度,但將高度縮小到酒吧自己的高度。這樣可以最大限度地挖掘可用區域(因爲標籤的自然高度可能只有〜22點,但酒吧的點高爲44點)。

+0

完美的解決方案。 我完全同意不通過視圖層次結構進行搜索,就像我發現的其他示例一樣,因爲將來可能無法使用。 非常感謝。 – Richard 2014-10-10 06:04:02

+2

我自己幾乎在那裏,但沒有懷疑'userInteractionEnabled'。 +1。 – 2016-09-28 08:59:40

+0

我有這個解決方案的問題。在稍後更新uilabel中的文本時,由於某種原因,標籤本身跳轉到x 0(屏幕最左側)。看起來像UIKit中的錯誤。反正周圍? (iOS 10.1.1) – Jonny 2016-11-04 02:28:00

15

這是一個解決方案,儘管不是超級優雅。在故事板中,只需在標題上放置一個常規的UIButton並將其附加到ViewController中的IBAction。您可能需要爲每個視圖執行此操作。

+2

這是很好的解決方案,實際上,可以完美運行,易於實現。 – Evgenii 2015-06-29 23:58:28

4

有一個更簡單,更優雅的使用手勢識別器的解決方案(至少在iOS 9及以上版本中)。

UITapGestureRecognizer * titleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(titleTapped)]; 
[self.navigationItem.titleView addGestureRecognizer:titleTapRecognizer]; 

然後添加標題挖掘方法:

-(void) titleTapped { 
    // Called when title is tapped 
} 
+3

不要忘記像接受的答案中那樣定義'self.navigationItem.titleView'。缺省值爲零。 – Jonny 2016-11-04 02:37:20

1

一個簡單的方法可能只是產生點擊手勢識別器並將其連接到您的導航欄元素。

// on viewDidLoad 
let tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(YourViewController.somethingWasTapped(_:))) 
self.navigationController?.navigationBar.addGestureRecognizer(tapGestureRecognizer) 

func somethingWasTapped(_ sth: AnyObject){ 
    print("Hey there") 
} 
+1

最好的方法來做到這一點。 – 2017-02-10 15:02:36

+3

在我的情況下,在另一個viewcontroller被推入堆棧之後,這打破了後退按鈕的功能。 – Georg 2017-03-10 15:59:46

+3

它會打破導航欄中其他按鈕的功能 – 2017-05-18 14:20:32

3

布魯諾的回答對我來說是90%。但我注意到的一件事是,一旦將此手勢識別器添加到其中,則導航控制器的UIBarButtonItem功能在其他視圖控制器中停止工作。爲了解決這個問題,我只是刪除從導航控制器手勢當視圖正準備消失:

var tapGestureRecognizer : UITapGestureRecognizer! 

override func viewWillAppear(_ animated: Bool) { 

    tapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(self.navBarTapped(_:))) 

    self.navigationController?.navigationBar.addGestureRecognizer(tapGestureRecognizer) 

} 

override func viewWillDisappear(_ animated: Bool) { 

    self.navigationController?.navigationBar.removeGestureRecognizer(tapGestureRecognizer) 

} 

func navBarTapped(_ theObject: AnyObject){ 

    print("Hey there") 

}