我最近将一个应用程序从模态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
}
由于
答案 0 :(得分:2)
正如@deadbeef在viewWillAppear和其他人中所说的超级电话。
加载和显示视图控制器视图的过程
故事板使加载和显示视图控制器视图的过程变得非常简单。 UIKit会在需要时自动加载Storyboard文件中的视图。作为加载过程的一部分,UIKit执行以下任务序列:
调用视图控制器的awakeFromNib方法。
调用此方法时,视图控制器的特征集合为空,视图可能不在最终位置。
调用视图控制器的viewDidLoad方法。
使用 viewDidLoad 方法添加或删除视图,修改布局约束, 并加载您的视图数据。通常重写此方法以对从nib文件加载的视图执行其他初始化。
在屏幕上显示视图控制器的视图之前,UIKit会为您提供一些额外的机会,让他们在屏幕之前和之后准备这些视图。具体来说,UIKit执行以下任务序列:
添加,删除或修改视图的大小或位置时,请记住添加和删除适用于这些视图的任何约束。对视图层次结构进行与布局相关的更改会导致UIKit将布局标记为脏。在下一个更新周期中,布局引擎使用当前布局约束计算视图的大小和位置,并将这些更改应用于视图层次结构。
答案 1 :(得分:2)
请注意,“它不起作用”实际上没有帮助。如果需要帮助,您需要详细描述代码执行或不执行的操作。
您的代码存在一些问题。
在viewDidLoad()
,viewWillAppear(_:)
和viewWillDisappear(_:)
中,您必须始终拨打超级电话。
在下次更新视图的布局之前,更新约束上的常量不会执行任何操作。
当你在viewDidLoad()
中更改布局约束时,它会在布局完成之前发生,因此更改将在下一个布局布局中应用。
如果要更改约束,则需要调用layoutIfNeeded()
。尝试将此添加到customizeApp()
功能:
func customizeApp() {
defer {
self.view.layoutIfNeeded()
}
}