![](/img/trans.png)
[英]Why viewDidAppear/viewWillAppear don't get called in a nested structure?
[英]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
}
謝謝
就像@deadbeef所說,在viewWillAppear等中調用super。
加載和顯示視圖控制器視圖的過程
故事板使加載和顯示視圖控制器的視圖的過程非常簡單。 UIKit會在需要時自動從情節提要文件中加載視圖。 作為加載過程的一部分,UIKit執行以下任務序列:
調用視圖控制器的awakeFromNib方法。
調用此方法時,視圖控制器的特征集合為空,並且視圖可能不在其最終位置。
調用視圖控制器的viewDidLoad方法。
使用viewDidLoad方法可以添加或刪除視圖,修改布局約束以及為視圖加載數據。 通常,重寫此方法可對從nib文件加載的視圖執行其他初始化。
在屏幕上顯示視圖控制器的視圖之前,UIKit給您一些額外的機會來在屏幕上之前和之后准備這些視圖。 具體來說,UIKit執行以下任務序列:
添加,刪除或修改視圖的大小或位置時,請記住要添加和刪除適用於這些視圖的所有約束。 對視圖層次結構進行布局相關的更改會導致UIKit將布局標記為臟。 在下一個更新周期中,布局引擎使用當前的布局約束來計算視圖的大小和位置,並將這些更改應用於視圖層次結構。
請注意,“它不起作用”確實沒有幫助。 如果需要幫助,您需要詳細描述代碼執行或不執行的操作。
您的代碼有幾處錯誤。
在viewDidLoad()
, viewWillAppear(_:)
和viewWillDisappear(_:)
您必須始終調用super。
在下一次更新視圖的布局之前,更新約束上的常量不會做任何事情。
當您在viewDidLoad()
更改布局約束時,該約束發生在布局完成之前,因此更改將在下一個布局通道中應用。
如果要更改約束,則需要調用layoutIfNeeded()
。 嘗試將其添加到您的customizeApp()
函數中:
func customizeApp() {
defer {
self.view.layoutIfNeeded()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.