Ios 为什么显示视图和隐藏视图时会出现或显示视图时不会出现';行不通

Ios 为什么显示视图和隐藏视图时会出现或显示视图时不会出现';行不通,ios,swift,uitabbarcontroller,viewwillappear,Ios,Swift,Uitabbarcontroller,Viewwillappear,我最近将一个应用程序从modalviewControllers转换为TabBarController,在转换之前有一些代码可以正常工作,但现在我很难在TabBar应用程序中工作 我想做的是根据存储在UserDefaults中的用户设置更新选项卡中的UI,这些设置发生在设置选项卡(ViewController)中,我想根据用户设置更新不同选项卡中的UI。转换之前,代码在ViewDidLoad中,工作正常,但现在使用TabBar没有ViewDidLoad我正在使用viewwillbeen,以便在选项

我最近将一个应用程序从modal
viewControllers
转换为
TabBarController
,在转换之前有一些代码可以正常工作,但现在我很难在TabBar应用程序中工作

我想做的是根据存储在
UserDefaults
中的用户设置更新选项卡中的
UI
,这些设置发生在
设置
选项卡(ViewController)中,我想根据用户设置更新不同选项卡中的UI。转换之前,代码在
ViewDidLoad
中,工作正常,但现在使用
TabBar
没有
ViewDidLoad
我正在使用viewwillbeen,以便在选项卡激活但不工作时立即更新

这是代码

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}
}
我还尝试了
viewdilayoutsubviews
,但也没有成功

你知道会出什么问题吗? 仅供参考-所有值均来自
UserDefaults

编辑: 我的问题是,我正在重新定位我的视图,但我没有将它们重新定位回原始位置。我知道这听起来很傻,但在切换到
uitabar
之前,当我从
ViewDidLoad
调用
customizeApp()
时,完全相同的代码工作正常,这一事实欺骗了我。最后,我从
viewdideappease()
方法调用了
customizeApp()

 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
}
谢谢

正如@deadbeef所说,在视图中将出现call super和其他内容

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

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

  • 使用序列图像板文件中的信息实例化视图

  • 连接所有插座和操作

  • 将根视图指定给视图控制器的视图属性

  • 调用视图控制器的awakeFromNib方法

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

  • 调用视图控制器的viewDidLoad方法

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

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

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

    请注意,“它不起作用”确实没有帮助。如果需要帮助,您需要详细描述代码做什么或不做什么

    您的代码有几处错误

    viewDidLoad()
    中,
    视图将出现(:)
    ,而
    视图将消失(:)
    您必须始终调用super

    在下一次更新视图布局之前,更新约束上的常量不会起任何作用

    viewdiload()
    中更改布局约束时,它发生在布局最终确定之前,因此更改将应用于下一个布局过程

    如果要更改约束,需要调用
    layoutifneed()
    。尝试将此添加到
    customizeApp()
    函数:

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

    始终在
    视图中调用super将出现
    和其他视图。否则你会破坏一切。你在哪里查看1,
    按钮1
    。。。来自哪里?好的。仅供参考,任何以viewWill/viewDid开头的内容都必须调用super。作为一般规则,在重写UIKit类时,除非文档明确要求不调用super。正如@deadbeef指出的,您应该添加:
    super.viewwillbeen(动画)
    super.viewdidebeen(动画)
    Ok,事实证明,我的问题是我重新定位了我的视图,但我没有将它们重新定位回其原始位置。我知道这听起来很傻,但当我从
    ViewDidLoad
    调用
    customizeApp()
    时,完全相同的代码工作正常,这一事实欺骗了我,但多亏了你的解释,我才能够找到问题。仅供参考-我不需要调用
    self.view.layoutifneed()
    我只是调用了
    customizeApp()
    from
    viewdide
    并通过调整约束将我的视图重新定位到其原始位置。非常感谢你的帮助!