2017-05-24 120 views
1

我看過所有類似的問題,我可以找到,我還沒有找到解決這個問題的方法。NavigationItem的titleView不能正確動畫

我設置titleView屬性像這樣在viewDidLoad

self.navigationItem.titleView = label 

視圖控制器是一個導航堆棧的一部分。當你點擊前一個視圖控制器中的一行時,它會將該控制器壓入堆棧。完全正常的UINavigationController的東西。

當這個視圖控制器開始動畫時,標籤出現在原點(左上角),然後停留在那裏直到視圖控制器完成動畫,然後它跳到(沒有動畫)到正確的位置導航欄。

點擊後退按鈕後,標題視圖會正常動畫,就像普通標題一樣。

這裏是viewDidLoad代碼:

let label = UILabel(frame: CGRect.zero) 
label.textAlignment = .center 
label.translatesAutoresizingMaskIntoConstraints = false 
label.backgroundColor = .red 
label.text = "test" 
label.sizeToFit() 
self.navigationItem.titleView = label 

事情我已經嘗試:

  • 指定一個框架:沒有變化。另外我不想指定一個框架。我不想對導航欄的高度進行假設。

  • 將其移動到viewWillAppear:沒有變化。

  • 將其移動到viewDidAppear:更好但仍不正確。在動畫完成之前,標籤一直沒有出現,然後出現在它應該出現的位置,沒有剛剛出現的動畫。正確的行爲是像正常的標題那樣從右向左動畫。

這很容易重現Xcode中的主 - 明細項目模板。如果你想嘗試,只需將上面的代碼添加到configureView()的頂部DetailViewController.swift。在該模板中,導航項目的標題被硬編碼到故事板中。您可以通過搜索「詳細信息」輕鬆刪除它。單擊Navigation Item: Title = "Detail"的結果,然後從「檢查器」窗格中刪除該字符串。


更新

@ synndicate的建議,併爲上述UILabel例子很好地工作。但我真正的問題是與UIStackView。當我使用@synndicate方法使用堆棧視圖時,我發現還有另一個動畫問題。這一次,標題視圖開始滑入,但一直到原點的動畫。動畫完成後,它會捕捉到它應該在的位置。

下面是prepare(for:sender:)代碼爲@synndicate建議...

let label = UILabel(frame: CGRect.zero) 
label.textAlignment = .center 
label.translatesAutoresizingMaskIntoConstraints = false 
label.backgroundColor = .red 
label.text = "test" 
let stackView = UIStackView(frame: CGRect.zero) 
stackView.translatesAutoresizingMaskIntoConstraints = false 
stackView.addArrangedSubview(label) 
stackView.sizeToFit() 
controller.navigationItem.titleView = stackView 

任何進一步的建議?

此外,這是Xcode 8和iOS 10。

更新2

我們已經發現,上述堆棧視圖代碼動畫完美(就像一個普通的標題會)在viewDidLoad爲一個視圖控制器,其中NAV層次結構的根是一個UINavigationController。當導航層次結構的根目錄爲UISplitViewController時,會發生此問題。

所以我想我可以更新我對這個問題......

如何配置將在navigationItemtitleView財產在導航層次結構的根是UISplitViewController設置一個UIStackView

回答

0

在將視圖控制器推入堆棧之前,是否可以將代碼移至?

例如在主從項目MasterViewController.swift

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "showDetail" { 
      if let indexPath = tableView.indexPathForSelectedRow {      

       let object = objects[indexPath.row] as! NSDate 
       let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController 
       controller.detailItem = object 
       controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem 
       controller.navigationItem.leftItemsSupplementBackButton = true 

       let label = UILabel() 
       label.textAlignment = .center 
       label.backgroundColor = .red 
       label.text = "test" 
       label.sizeToFit() 

       controller.navigationItem.titleView = label 

      } 
     } 
    } 
+0

針對其添加到您的更新,在這一點上,我建議你不得不重構和子類UINavigationController在那裏你設置你的titleView那裏。然後在將來'準備(for:sender)'調用你可以設置特定於控制器的文本被推送 – synndicate

0

如果你想在stackView出現在導航堆棧的特定視圖控制器,只需在視圖控制器

self.view.addSubview(stackView) 
+0

正確。但它不會在任何地方。我試圖在導航項目的titleView中使用堆棧視圖。所有細節都在上面。 –

+0

爲什麼你需要將它添加爲'titleView'? 'titleView'是爲了在整個導航過程中持續使用_only_。 –

+0

我想在導航欄的標題中添加多個標籤。我的理解是,每個視圖控制器都可以像「title」一樣設置navigationItem的'titleView'。 –

相關問題