Right now I'm doing this:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated);
self.loadObjects()
}
But every time I use loadObjects(), the screen briefly flashes. I don't know how to fix it. I am using a TabBarController (no segues between views), so each view is only loaded once, and I want to update each view when I navigate to it. loadObjects() works, it just creates this annoying visual bug. I assume that the old view is cached and is desplayed before the new one is loaded, and that's why I see this flash. Any suggestions?
Related
In my TvOS app I have a viewController with UISearchContainerViewController. Here is the tree of views:
and
The searchController looks good and work as needed. From this viewController I can go to another one and from there open another instance with initial viewController (with searchController). In this another instance the everything is well too. BUT, when i pop back to the first instance the keyboard disappearing and the tree looks like:
I think it's because the instance of the system keyboard is shared across the app. But i don't know how to fix that. Can you help me?
private var keyboardContainer: UISearchContainerViewController!
In initialController I did add
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
keyboardContainer.searchController.searchBar.becomeFirstResponder()
}
and it seems that fixed the issue.
I have a small problem I sadly couldn't solve. I have a few ViewControllers. I need to call a function when going back from a ViewController to the previous ViewController (which does not reload, so viewDidLoad / Appear is not called).
Mustn't there be anything like viewDidLoad, but gets called every time the ViewController is visible?
This is how I open the ViewControllers:
let vc = storyboard?.instantiateViewController(identifier: "levels_vc") as! LevelsViewController
present(vc, animated: true)
This is the way I try to get the event, but it only gets called the first time (when the ViewController loads the first time), but not when I open a new ViewController from this one and close the new one.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("VC appeared!")
}
You can use viewWillAppear or viewDidAppear for that purpose!.
viewWillAppear() is called every time the view will appear on the screen.
This can be useful for views that need to be updated every time they’re scrolled to. For example, the Now Playing section in a music app or any view that is updated when it is scrolled to.
viewDidAppear is called when the view has appeared on the users screen.
This is a good place to “lazy-load” any other elements onto your screen. If your user interface is very complicated, you don’t want to stall or cause a delay in the previous mentioned methods.
It’s better to load something onto the screen and then call some methods to update the views for some large applications.
This is also a create place to start any animations.
That would be ViewDidAppear() ViewDidAppear() - Apple Developer
I have a very linear app that uses a Navigation controller to go through a series of View Controllers. All segues are handled in the storyboard and set to "Push" (that's the only way I can get the navigation controller to work...)
Start with a 'menu' VC with options, select one and it takes you to another VC. Sometimes the next VC is another menu (more detailed) but sometimes the VC is an SCNView that shows an SCNNode. Navigating through the VCs is working perfectly, thanks to the Navigation Controller.
The problem comes whenever you go to one of the SCNViews and then back out (to a menu or previous VC). Particularly, switching from menu to SCNView, back to menu, back to same SCNView, over and over builds up memory until the app crashes.
ARC seems to not be releasing the SCNNodes/SCNViews when navigating out of them. Every SCNNode/Scene/View I set up as weak AND I've tried all kinds of combinations of the following code in each/all the VCs:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
self.dismiss(animated: true, completion: nil)
}
I put this at the end of each VC but it still seems that the SCNNodes are getting retained and the memory builds up until it crashes.
How can I clear the SCNNodes when I exit the VC? Since I declare everything as weak inside ViewDidLoad, I can't call/set anything in the ViewWillDisappear func since it's outside of that.
I encountered a problem while trying to present a new view controller within a storyboard using following code:
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("ViewControllerIdentifier")
self.presentViewController(viewController!, animated: true, completion: nil)
The view controller does appear, but shows for some reason only two buttons, no other elements.
What have I tried so far:
Loading the view controller as initial view controller to see if the
problem remains.
No, all elements are at the right position.
Switching animated from true to false. Problem still remains
Printing the hidden attribute as well as x and y positions. Hidden
is false, and the positions are what they are supposed to be
Cleaning and rebuilding the project, since this seems to fix 99% of
all strange bugs based on my experience. Sadly this helped not this
time
Setting hidden first on true, then on false. Resetting the attribute
does not help.
Using CFRunLoopWakeUp(CFRunLoopGetCurrent()) . Does not help
either.
I have a simple drawing of what my view looks like attached.
As stated, the view controller is shown perfectly fine when I load it as initial view controller, but only the buttons are shown when using the code above.
ViewDidAppear is called as well.
I am using Xcode Version 7.2.1
EDIT:
As requested by comment, this is my code for the view controller to be presented:
import UIKit
class myViewController : UIViewController {
#IBOutlet weak var myImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
}
Edit:
I found a solution to this problem:
By creating the transition within the following block.
dispatch_async(dispatch_get_main_queue(),^{
});
It appears that my problem was, that the lines that trigger said transition weren't executed on the UI thread. I still have no idea why this lead to the behaviour explained above, but at least there is a solution.
In my experience problems like this can be down to your auto layout constraints being messed up or not quite as you need them (although the fact that it presents correctly when it is the default might suggest I am not headed down the right path).
Are there any warnings in the storyboard editor that suggest the constraints are not correct? I would also suggesting using the view debugging feature to help troubleshoot. Click on the circled icon when your app is running to show your view hierarchy and then try to find the views you think should be there. It also allows you to look at constraints, so that might help with point 1 above as well.
I'm working on a app which has a button to open a view that access the camera.
So, I have a button to trigger a segue (using the storyboard) and in my other view, inside viewDidLoad(), I'm doing all I need to start the video capture.
The problem is that between touching the button and view been showed it take some small amount of time and I don't like it.
If I comment all the stuff regarding the video capture, the view show up instantly.
So, I think the lag is du to the preparation to access the camera.
How to display the view, an empty view, and then doing the stuff to show the camera?
If you want to show the new view controller and then activate the camera, move your code from viewDidLoad into viewDidAppear. You could try viewWillAppear, but depending on what your code does, you may just see the same issue you have now.
You have to be careful here to only do your activation once as viewWill/DidAppear can be called multiple times: especially as a result of being exposed when a controller you push on top is popped.
Just use viewDidAppear to load all the methods in that view controller instead of using the viewDidLoad method like so:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}