簡體   English   中英

為什么從viewWillAppear或viewDidAppear中顯示和隱藏視圖不起作用

[英]Why showing and hiding view from viewWillAppear or viewDidAppear doesn't work

我最近將一個應用程序從模態viewControllers轉換為TabBarController並且在轉換之前有一些可以正常工作的代碼,但是現在我很難使它在TabBar應用程序中正常工作。

我想做的是根據UserDefaults存儲的用戶設置更新選項卡中的UI ,這些設置發生在“ Settings選項卡(ViewController)中,我想根據用戶設置的Settings來更新其他選項卡中的UI。用戶。 轉換之前,代碼在ViewDidLoad ,並且工作正常,但是現在使用TabBar ,沒有ViewDidLoad我正在使用viewWillAppear,只要激活了選項卡但就無法正常工作,就進行更新。

這是代碼...

class UserInputViewController: UIViewController{

    override func viewDidLoad() {
        super.viewDidLoad()
        // customizeApp() // everything works if called from here
    }

    override func viewWillAppear(_ animated: Bool) {
        customizeApp() // Doesn't work
    }
    override func viewDidAppear(_ animated: Bool) {
        // customizeApp() // Doesn't work
    }

     func customizeApp(){

        if isView1(){
            view1.isHidden = false
        }else{
            view1.isHidden = true
        }

        if isButton1(){
            button1.isHidden = false
        }else{
            button1.isHidden = true
        }

        if isTextField1(){
            textField1.isHidden = false
        }else{
            textField1.isHidden = true
        }

        if isTextField2(){
            textField2.isHidden = false
        }else{
            textField2.isHidden = true
        }

        /// Adjust Screen based on settings
        if textField1.isHidden && textField2.isHidden{
            constraintMainButton.constant = 7
            return
        }
        if textField1.isHidden {
            constraintMainButton.constant = 45
        }
        if textField2.isHidden {
            constraintMainButton.constant = 45
        }
    }

    func isView1()->Bool{// read UserDefaults}
    func isButton1()->Bool{// read UserDefaults}
    func isTextField1()->Bool{// read UserDefaults}
    func isTextField2()->Bool{// read UserDefaults}
}

我也嘗試過viewDidLayoutSubviews但它也不起作用。

知道有什么問題嗎?

僅供參考-所有值均來自UserDefaults

編輯:

我的問題是我正在重新定位自己的觀點,但沒有將它們重新定位回原來的位置。 我知道這聽起來很愚蠢,但是當我在更改為UITabBar之前從ViewDidLoad調用ViewDidLoad customizeApp()時,完全相同的代碼可以正常工作,這讓我感到ViewDidLoad 最后我打電話customizeApp()viewDidAppear()方法。

 class UserInputViewController: UIViewController{

    /// ... Code

    override func viewDidAppear(_ animated: Bool) {
        customizeApp()
    }

     func customizeApp(){

        /// ... Code

        /// Adjust Screen based on settings
        if textField1.isHidden && textField2.isHidden{
            constraintMainButton.constant = 7
            return
        }
        if textField1.isHidden {
            constraintMainButton.constant = 45
            return // added
        }
        if textField2.isHidden {
            constraintMainButton.constant = 45
            return // added
        }

        constraintMainButton.constant = 83 // added: Original Position
    }
    /// .... Code
}

謝謝

Apple文檔

就像@deadbeef所說,在viewWillAppear等中調用super。

加載和顯示視圖控制器視圖的過程

故事板使加載和顯示視圖控制器的視圖的過程非常簡單。 UIKit會在需要時自動從情節提要文件中加載視圖。 作為加載過程的一部分,UIKit執行以下任務序列:

  1. 使用情節提要文件中的信息實例化視圖。
  2. 連接所有出口和動作。
  3. 將根視圖分配給視圖控制器的view屬性。
  4. 調用視圖控制器的awakeFromNib方法。

    調用此方法時,視圖控制器的特征集合為空,並且視圖可能不在其最終位置。

  5. 調用視圖控制器的viewDidLoad方法。

使用viewDidLoad方法可以添加或刪除視圖,修改布局約束以及為視圖加載數據。 通常,重寫此方法可對從nib文件加載的視圖執行其他初始化。

在屏幕上顯示視圖控制器的視圖之前,UIKit給您一些額外的機會來在屏幕上之前和之后准備這些視圖。 具體來說,UIKit執行以下任務序列:

  1. 調用視圖控制器的viewWillAppear:方法以使其知道其視圖即將顯示在屏幕上。
  2. 更新視圖的布局。
  3. 在屏幕上顯示視圖。
  4. 屏幕上顯示視圖時,調用viewDidAppear:方法。

添加,刪除或修改視圖的大小或位置時,請記住要添加和刪除適用於這些視圖的所有約束。 對視圖層次結構進行布局相關的更改會導致UIKit將布局標記為臟。 在下一個更新周期中,布局引擎使用當前的布局約束來計算視圖的大小和位置,並將這些更改應用於視圖層次結構。

請注意,“它不起作用”確實沒有幫助。 如果需要幫助,您需要詳細描述代碼執行或不執行的操作。

您的代碼有幾處錯誤。

viewDidLoad()viewWillAppear(_:)viewWillDisappear(_:)您必須始終調用super。

在下一次更新視圖的布局之前,更新約束上的常量不會做任何事情。

當您在viewDidLoad()更改布局約束時,該約束發生在布局完成之前,因此更改將在下一個布局通道中應用。

如果要更改約束,則需要調用layoutIfNeeded() 嘗試將其添加到您的customizeApp()函數中:

func customizeApp() {
  defer {
     self.view.layoutIfNeeded()
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM