Most of the iOS apps I use are very responsive, when I tap on an element it goes to the next view right away. In my app, some of my view controllers take 0.5-1.0 second to load.
My code is all in the viewDidLoad method and I'm pretty sure that's the problem but I can't move anything out since I need every single element that I instantiate.
A solution I thought is to move all the work I do in viewDidLoad in a thread then call the main thread when I'm ready to call addSubview, would that work even if UIKit is not thread safe? Or is there something else I'm missing?
Try to move some code you might have in viewDidLoad to viewdidAppear. viewDidAppear is being called once the view is presented. If you have to make some hard work, do it there and maybe show aa spinner somewhere while you do that.
What are you exactly doing in viewDidLoad? Btw remember that a view is only loaded when you need it, if you want to switch between views faster I can suggest you to create an initializion phase where you call -view on all the view controller you want to show, maybe helped with a spinner or a progress bar. but pay attention this would work only with intensive loading task and not memory consuming tasks. It sounds very strange your request, so is better the you try to explain better why your viewDidLoad is so slow, maybe there is something wrong.
Define your UI elements in Xcode as part of designing the interface. That way, Xcode can compile your storeyboard or xib files into the rapidly loading binary form.
Related
I have a simple UIViewController whose view is created via a Nib. Here's the structure of the Nib:
And a screenshot of the layout:
Whatever the previous view (there are 2 possibilities), there is significant stutter/lag when transitioning to this view. Even the keyboard animation is lagged. Also, this is only on an actual device.
I've tried removing the MKMapView to see if that was the case, but it didn't make a difference.
Is the Nib too complex? Should I load everything via code? I'm not sure what it could be, but its really annoying, especially when the rest of the app is super crisp.
As far as code goes, its nothing special: just alloc/init a view, push it onto a UINavigationController, etc. Nothing in the viewWillAppear:/viewWillDisappear:.
Coming from Reddit, where you posted code (probably want to do that here too):
My guess would be the lag is coming from the section from line 44 through 80ish, where you build the overlay. Something in there might be taking longer than you think (Spotpoint unSerialize sounds fishy). You typically want to do as little work as possible in viewDidLoad, since that is called as the UI is transitioning to the new view controller.
Try throwing that code into a GCD queue or running it in the background, and see if that helps the loading stutter.
I'm doing an app that uses a TabBarController and each Tab uses its own navigation controller.
The app has dynamic content and I use viewDidDisappear viewDidAppear methods to create or destroy the objects that I need each time I enter or exit into the ViewController.
My problem is when I start to sail very fast and I don't give time to load the Threads that I use for uploading content such as XML peta app or destroy objects when I leave the ViewController.
How I could control the tabs of the navigationbar or tabbarviewcontroller for not respond until the viewcontroller has loaded all contents?
Excuse me if I'm not well expressed. Thanks!
No matter you use synchronous request or asynchronous request, just show an UIAlertView while loading the data. This will both serve as a notification to the user that something is being loaded, and the it will block the interactions with all the other views on the screen.
As others have suggested in comments, I believe that what you want to do is rearrange the order in which things are triggered. Perhaps something like this:
On viewWillAppear:, clear (or disable or whatever is appropriate) your objects that are no longer valid and begin the load-new-content thread. Perhaps display a UIActivityIndicator or similar.
On viewWillDisappear:, tell the load-new-content thread that it can stop, its results are no longer needed. If you put up an activity indicator, take it down.
At the end of the load-new-content thread, take down any activity indicator, update the UI with the new contents and activate.
I don't really see any way around this -- if the UI is not valid until the new content is loaded, then you have to wait for it.
Another solution might be to cache the contents from the previous fetch, and always display those on viewDidLoad. Then, at the end of your new-content-thread, cache the new contents, and update the UI.
Ok hopefully this is an easy question:
I have a main viewcontroller that is loaded by the app delegate at application startup.
This viewcontroller has some code in 'viewDidLoad' to create some non view type based objects (some sound/data objects). Aside from that it also loads a UIView.
The sound/data objects take a while to create, but the app is quite functional without them for a start - so I want to load these objects after the UIView has loaded, but can't seem to figure out how.
I have tried moving the appropriate code to viewDidAppear, but this is still called before the UIView actually appears on screen. Is there a function that is called after the viewcontroller actually starts displaying UIViews, or any other way to achieve what I want?
Any help would be much appreciated - thanks!
In case anyone else has a similar problem, I found a way to solve it: use NSThread to load things in the background without pausing everything else.
There's a good simple example here: http://www.iphoneexamples.com/.
I already had a question like this, but I already deleted it anyway.
I have very simple app that has a root view controller and it switches between two other view controller views. So in my root view controller, It lazy loads the instances of the two other view controllers. Each time the switch button in the toolbar is pressed, the current view controller being displayed (its view) is unloaded (set to nil), and the new one is loaded and added to the subview.
Since I load my view controllers and unload at specific times, the lazy loading code being in the getters is very confusing because I don't actually want to load them right when I use them, I need to load them before so the flip animation will look good. So I think I want to make loadFirstVC and loadSecondVC methods to load the view controllers. Is this a good idea?
The main reason for lazy-loading is NOT to defer loading that will definitely occur. It is for deferring loading that may never be needed. (It's also good for forcing reloads when the data has changed, but that's not your issue here.)
Example: Let's say you have a bunch of data about a person, including a photo, which is stored in an external file. But the photo will only be displayed if the user goes to a subview, so why load the photo from its file until you know for sure that the subview is going to appear? Boom, use lazy loading.
By the time you KNOW you want to load a certain piece of data, it's unlikely to matter very much when exactly you load it.
When does it matter? Well, that's really a matter of optimization. There's a saying you may have run across; if you haven't, this is as good a time as any: "Premature optimization is the root of all (programming) evil."
So ask yourself two questions:
Will the piece of data definitely be needed? If NO, proceed with the lazy-loading technique. If YES, go to question 2.
Does it MATTER when I load the data? [An example would be, it's huge and I don't want to load it until I've UNLOADED something else to make room for it] If NO, put it any place that works. If YES... Come back and ask us again, and provide more details.
...I suspect this doesn't answer your original question, but it sounds like you may be asking the wrong question in the first place. Apologies if I'm mistaken.
So I'm trying to use a UITableViewController (let's call it homeView) in my iPhone application to display a simple table with only a few rows of text which are loaded from an NSArray in the controller. I want to display the table in the grouped style in a subview of a subview (let's call it subSubView) of my main controller. When I try the following: [subSubView addSubview:homeView.view], my app crashes on launch. However, when I allocate the object without adding it to any views, it launches fine.
What's the best way (or rather a working way) to display the table generated by my UITableViewController?
There isn't enough to tell for sure what is going on, but if I had to guess I would think that you probably aren't retaining homeView. Normally I would say that as a comment to your question, since it is not really an answer, but I have a completely separate answer:
Just use a UITableView, not a UITableViewController. Instead of trying to embed a controller within a controller (which is quite difficult since Apple doesn't expose the necessary tools to actually modify the view controller hierarchy), just make the VC you are writing support the appropriate delegate/dataSource methods and directly create the view.
While it might make some logical sense to try to embed VCs inside of each other, with the exception of the builtin container VCs (UINavigationController, UITabBarController) it Really Doesn't Workâ˘. The technical reason for this is that internally some of the event routing and messaging depends on parentViewController being correct, but since you can't set it (setParentViewController: is private) tons of latent bugs in UIKit start rearing their head. The internal collection classes can set the parentViewController correctly, so everything works right.
Also, one last thing. In your question you named your view controller homeView. Please, please on't do that. A view controller and a view are separate things, call it homeViewController. Aside from the fact that a lot of new iPhone developers get confused about what the distinction is, there is nothing more aggravating then tracing through someone else's code and realizing that something you are assuming is one type is another.