I recently converted an app from modal viewControllers
to TabBarController
and there is some code that used to work fine before the conversion but now I'm having a hard time making it work in the TabBar app.
What I want to do is update the UI
in a tab based on user setting stored in UserDefaults
, these settings happen in the Settings
tab (ViewController) and I want to update the UI in a different tab based on the settings that were set by the user. Before the conversion the code was in the ViewDidLoad
and it was working fine but now with TabBar
there is no ViewDidLoad
I'm using viewWillAppear, to update as soon as the tab is activated but isn't working.
Here is the code...
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}
}
I also tried viewDidLayoutSubviews
but it didn't work either.
FYI - All values come as expected from UserDefaults
.
My Issue was that I was repositioning my views but I wasn't repositioning them back to their original position. I know it sounds silly but I was tricked by the fact that the exact same code was working fine when I was calling customizeApp()
from ViewDidLoad
before changing to UITabBar
. I ended up calling customizeApp()
from viewDidAppear()
method.
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
}
Thanks
Note that "it doesn't work" is really un-helpful. You need to describe what your code does or doesn't do, in detail, if you want help.
There are several things wrong with your code.
In viewDidLoad()
, viewWillAppear(_:)
, and viewWillDisappear(_:)
you must always call super.
Updating the constant on a constraint doesn't do anything until next time the view's layout is updated.
When you change your layout constraints in viewDidLoad()
, it takes place before the layout has been finalized, so the changes are applied in the next layout pass.
If you want to make changes to constraints, you need to call layoutIfNeeded()
. Try adding this to your customizeApp()
function:
func customizeApp() {
defer {
self.view.layoutIfNeeded()
}
}