I have SplashScreenController where it has progress bar. And I want to preload web view while progress bar ends. Also I have WebViewController where I load web view.
So as I understood I have to load web view in SplashScreenController. How I can get WebViewController view in SplashScreenController
You cannot do that way. Basically, what you need to do is load WebViewController first, and at same time (on viewDidload for example), load the SplashScreenController as Modal. This way you can send message from WebViewController to SplashScreenController (ie, progress of loading, etc).
In my experience a UIWebView won't start loading content unless it is in the view hierarchy. It doesn't mean it has to be visible, I usually put them off screen and show them only when load is completed. You can put the UIWebView in a different UIViewController, as long as that VC is loaded. The Splash screen can stay on top and be connected either to the same VC as the web view or to a different one (I'd suggest the second approach)
Do webviewcontroller as a starting. Start downloading web content on it. From above, put a view on the whole screen, with a progress bar. Upon completion of the progress bar, simply delete the subview. Will remain webviewcontroller loaded with content. With Splash screen you cannot do anything, because as long as it is present, in AppDlegate didFindishLaunchingWithOptions method not called and the application does not exist
Related
In my app, I have an UITableView with asynchronous data loading : when the view controller is loaded I show a modal activity spinner and start the HTTP request. When it is completed I hide the spinner and execute reloadData() on my table view. I also return response?.count ?? 0 as a number of rows to make sure that the list it initially empty when the data is not ready yet.
It works like a charm, but I have an issue with VoiceOver : when opening the view controller, VoiceOver goes into the table and says "empty list". When the data is loaded it goes to the last element of the table.
This behavior is not very optimal : I would like VoiceOver to not focus the table while it's empty (it doesn't need to focus the modal spinner since we already have a sound while loading) and then go to the first element when it's loaded.
How may I do that ?
You want to set up your loading overlay screen as a modal view. Modal means that the things behind the view are not actionable (or focusable by VoiceOver).
//Instantiate a view controller with your loading spinner.
_modalDialogViewController = [[UIStoryboard storyboardWithName:#"ModalDialog" bundle:[NSBundle mainBundle]]
instantiateViewControllerWithIdentifier:#"AccessibleSpinnerModal"];
//Make this view controller modal, meaning only things on this screen will be actionable/focusable.
_modalDialogViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
You may also then need to use accessibility notifications in either of these styles.
//Announce that content is loading directly
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, "Stuff is laoding");
Or
//Shift focus to the view in your modal that is sharing the status of the loading content.
UIAccessibilityPostNotification(UIAccessibilityLayoutChanged, spinnerView);
This will cause focus to move to that view.
I am working on a app using UIWebView now getting a issue listed below please help me to sort it out.
In my UIWebView, I show some HTML content from String in it.
However, when I go to another ViewController and return back, it goes white for a second then draws my HTML content again.
Is there any way to prevent this? My html content does not change, so can I set it as fixed content or something to draw it faster ?
This is how I set html in webview:
webView.loadHTMLString(htmlData, baseURL: nil)
Your HTMl code is not changing, so that put your webView load code inside viewDidLoad instead of viewDidAppear, because viewDidAppear always call when your view is appear, where as viewDidLoad called single time when your view is load.
you can execute the code which is directing webview once in a life cycle of app or customize accordingly.
// if you are navigating your application using navigation controller enables you to come back to the rootview without executing whole code of that class associated with view.
// this doesn't apply the whole life cycle of view controller
[self.navigationController pushViewController:vc animated:YES];
// if you navigating through below code this apply the whole life cycle concept of view controller.
[self presentViewController:vc animated:NO completion:nil];
you must have a look about the life cycle of view controller here is a useful apple doc
viewController Life cycle short note
ViewDidLoad - Called when you create the class and load from xib. Great for initial setup and one-time-only work.
ViewWillAppear - Called right before your view appears, good for hiding/showing fields or any operations that you want to happen every time before the view is visible. Because you might be going back and forth between views, this will be called every time your view is about to appear on the screen.
ViewDidAppear - Called after the view appears - great place to start an animations or the loading of external data from an API.
ViewWillDisappear/DidDisappear - Same idea as ViewWillAppear/ViewDidAppear.
ViewDidUnload/ViewDidDispose - In Objective C, this is where you do your clean-up and release of stuff, but this is handled automatically so not much you really need to do here.
I am using uiwebview to show my web contents. Navigating to different url using RevealViewController. I am caching all the pages for the first time entry.
After visiting few pages when trying to goto rear view (reveal view controller menu screen), the app got stuck for some time on clicking of the menu button.
(Every time visiting and caching a page that will increase the memory size of the app)
If the presentation of the menu is slow, it is probably because you are doing some heavy processsing inside the initialiser of the menu or the viewDidLoad function, or the menu button pressed function.
My suggestion is to move any of that processing to the viewDidAppear method of your menu controller instead, so that the UI is not blocked by any processing you do. You could also use GCD to disaptch_async anything that is intensive.
If you give some code examples it will be easier to see exactly what the problem is, particularly the code that executes when the menu button is pressed.
I'm working on a problem where I have a ViewController which opens a popOver when a button is pressed and then in the popOver you can edit some settings which affect the content shown in the mother ViewController (for instance change the color of the View, change a map or a table there). This can be off course called whenever the popOver is dismissed, but it needs to be live up-to-date.
I tried using delegates, where I can pass over data or call a function but the function won't be started on a ViewController wchich isn't active, right?
I also tried NSNotifications but it didn't work either.
I found several questions like this on stackoverflow, but there is no real answer yet:
UIPopoverController button selecting method of another ViewController but not updating its view iOS
Refresh the view controller from popover
Refreshing a view from a popover
Refresh a WebView in a ViewController from another ViewController
how to refresh or reload a uiviewcontroller
Can somebody please explain a generall way with some code snippets how to get this fixed?
Delegation is a fine solution. The target view controller is presumably still visible underneath the popover (which shouldn't fill the screen). In this case when the target receives the delegate callback it can do any updates and refresh its views to update the UI without any limitation. In this situation both view controllers (the 'target' and the popover) would both be classed as 'active' as they are both visible on screen.
I have an app that opens with a splash screen (Default.png), then loads the first view (ViewController1) in a navigation controller. Straight away, an instance of ViewController2 (VC2) is created, and pushed onto the navigation controller:
[self.navigationController pushViewController:VC2 animated:NO];
So when I run the app, the default image is displayed, then the view of ViewController1 is briefly displayed until ViewController2 is loaded (and then displayed).
How can I stop the brief display of ViewController1? Can I extend the display of Default.png until VC2 is displayed, or cover ViewController1 with the Default.png image until VC2 shows?
Thanks so much.
If the only thing you want to do is to show VC2 without showing VC1, in the viewDidLoad method of your VC1 you can do self.view.hidden = YES; then push the VC2 without animation
I think in your case, you want VC2 to be your starting point with VC1 as your ad-hoc splash screen. The default.png images should be a way to mirror the look of your app to give the impression your app is starting and working faster than it may appear. (This is taken from Apple's HIG)
You may want to consider making VC1 your new splashscreen/loading screen. You could make it into a simple waiting or loading page then load VC2 once everything in your app has been taken care of. Default.png could be an image of the loading screen and would give the impression your app is loading right away.
There are many differing opinions of how to approach this issue. You will ultimately have to decide which method is best for you and your application.
One final thought, you could load directly to VC2 and just present a loading progress view. I have used MBProgressHUD to lock the user out while I load information or perform tasks they need to wait for. This could be another option. Hope this information helps.
You can add a UIImageView to VC1 with Default.png, then remove it in viewDidDisappear:.
I don't think you can modify the Default.png behaviour. I would suggest you create an UIImageView in ViewController1 with Default.png as its image. Give it the exact same size as the screen and add it as a subview that completetely covers it. That way you will see Deafult.png twice and after it will go to ViewController2