为什么在viewWillAppear或viewDidAppear中显示和隐藏视图不起作用

时间:2017-06-22 13:01:10

标签: ios swift uitabbarcontroller viewwillappear

我最近将一个应用程序从模态viewControllers转换为TabBarController,并且有一些代码在转换之前曾经工作正常,但现在我很难在TabBar应用程序中运行它

我想要做的是根据UI中存储的用户设置更新标签中的UserDefaults,这些设置发生在Settings标签(ViewController)中,我想要更新基于用户设置的设置,在不同选项卡中的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

编辑:

我的问题是我正在重新定位我的观点,但我没有将它们重新定位回原来的位置。我知道这听起来很愚蠢,但是当我在更改为customizeApp()之前从ViewDidLoad调用UITabBar时,完全相同的代码工作正常。我最终从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
}

由于

2 个答案:

答案 0 :(得分:2)

来自Apple Documentation

正如@deadbeef在viewWillAppear和其他人中所说的超级电话。

加载和显示视图控制器视图的过程

故事板使加载和显示视图控制器视图的过程变得非常简单。 UIKit会在需要时自动加载Storyboard文件中的视图。作为加载过程的一部分,UIKit执行以下任务序列:

  1. 使用情节提要文件中的信息实例化视图。
  2. 连接所有商店和行动。
  3. 将根视图分配给视图控制器的视图属性。
  4. 调用视图控制器的awakeFromNib方法。

    调用此方法时,视图控制器的特征集合为空,视图可能不在最终位置。

  5. 调用视图控制器的viewDidLoad方法。

  6.   

    使用 viewDidLoad 方法添加或删除视图,修改布局约束,   并加载您的视图数据。通常重写此方法以对从nib文件加载的视图执行其他初始化。

    在屏幕上显示视图控制器的视图之前,UIKit会为您提供一些额外的机会,让他们在屏幕之前和之后准备这些视图。具体来说,UIKit执行以下任务序列:

    1. 调用视图控制器的viewWillAppear:方法让它知道 它的观点即将出现在屏幕上。
    2. 更新视图的布局。
    3. 在屏幕上显示视图。
    4. 当视图在屏幕上时调用viewDidAppear:方法。
    5. 添加,删除或修改视图的大小或位置时,请记住添加和删除适用于这些视图的任何约束。对视图层次结构进行与布局相关的更改会导致UIKit将布局标记为脏。在下一个更新周期中,布局引擎使用当前布局约束计算视图的大小和位置,并将这些更改应用于视图层次结构。

答案 1 :(得分:2)

请注意,“它不起作用”实际上没有帮助。如果需要帮助,您需要详细描述代码执行或不执行的操作。

您的代码存在一些问题。

viewDidLoad()viewWillAppear(_:)viewWillDisappear(_:)中,您必须始终拨打超级电话。

在下次更新视图的布局之前,更新约束上的常量不会执行任何操作。

当你在viewDidLoad()中更改布局约束时,它会在布局完成之前发生,因此更改将在下一个布局布局中应用。

如果要更改约束,则需要调用layoutIfNeeded()。尝试将此添加到customizeApp()功能:

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