I'm new to iOS. I have a storyboard with a navigation controller as initial view controller:
And I need some splash screen as a first screen after Launch screen to determine if user has a subscription or not. Depending on the result, I want to get to navigation view controller which is now initial view controller or to subscription screen (which is now the third in the tree).
In the second case, I want to save the existing structure where the navigation controller remains at the top
I found a couple of manuals, but they did not work in my case. How to do it properly?
tell me if i have not indersttod well. #Victor Pro his solution inspired me.
//1.
You need a like SplashScreenVC after launch screen. so in storyboard you can set it as a initial view controller.
//2. After determining in any case
Preset a Initial Navigation Controller which is your main controller.
subscriptionNeeded = true , if subcription needed
///3. If your subscription needed then
take one flag in appdelegate/global variable that subscriptionNeeded , and set it true.
///3.1 when you do point 2, in that in navigation controller -> root view controller -> View Will Appear
if subscriptionNeeded {
subscriptionNeeded = false
Push / Preset a sunscription VC
}
Tell me if i am not getting. Or u not get what i wrote.
Related
so I have a simple application using a storyboard. I have a few view controllers linked by segues. I also have one controller set as the default "first view controller". I understand that no code is required for the app to automatically load this was the first controller. However I want the app to first run a few checks (i.e. is the user logged in) before it decides which controller to push. Is there anywhere I should be putting this code or should I remove the "first view controller" setting on the storyboard and init manually?
Thanks
you can set the LoginViewcontroller as initial viewcontroller and if the user is logged in change the initial viewcontroller to something else, you can change the initial view controller by changing the rootViewController property of the window
I would leave your first controller as is, and check in AppDelegate if you want to show Login screens. If you do show them push that controller, otherwise, show your "first view controller".
I have an app with a tab bar controller with 4 tab bar item , every tab bar item display a view controller and viewDidLoad start a query parse Method .
From first ios8 beta when the device ( or simulator ) change orientation the app launch all view controller viewDidLoad method and consequently start query parse Method in all view controller !
How can i stop this !
Where am I missing?
Thanks so much!
P.S. : Excuse for my terrible english ;-)
This seems to be the behavior going forward. You'll need to change you code to handle it. You'll have to move it to view will appear possibly with a bool/date to track when you last loaded your data.
You'd need to refactor something like this:
Create a BOOL property for the VC something like loadedData
Take your loading code from viewDidLoad and move it into viewWillAppear: wrapped in a check if (!self.loadedData) { }
I have a One main view controller and in that I am having two sub view controllers named like rightViewcontroller and leftViewcontroller. When we press the menu items from the right view then I am changing the left view controller.That's working fine.Here my problem is If I get any alert that's only fixed to any of the View controller's.Then user able to press the other view which is not having the alert(those are custom alert's. I need custom alerts as per the client requirement)in iPad. Please Help me
Thank's in advance
When you get an alert on, say, the leftViewController, then disable the user interaction on the other viewControllers.
something like:
rightViewController.view.userInteractionEnabled = NO;
It seems when you present your alert you are showing it over one of the views like showInView:self.view when in fact you should show it over the parent view so it covers both like showInView:self.navigationController.parentViewController.view (that's just pseudo code).
Without seeing your code you use to present it currently I can't give you exact code.
Another way would be to first get a pointer to the parent view controller or navigation controller and show it there.
I have a custom container view controller: ContainerVC. Its job is to present one of two content view controllers: ContentPortraitVC or ContentLandscapeVC, depending on the current orientation (though it doesn't matter why the container chooses its view, I presume). ContentPortraitVC, at some point pops up ContentModalDetailVC.
So there are two different methods of displaying new content at work here:
the parent-and-child relationship (instigated via addChildViewController and removed via removeFromParentViewController),
the presenting-and-presented relationship (instigated via presentViewController and removed via dismissViewController).
If the ContainerVC adds the ContentPortraitVC, which then presents the ContentModalDetailVC, and then the ContainerVC decides to switch to the ContentLandscapeVC, the ContentModalDetailVC stays visible (why is it not removed when its parent is removed?)
But then, when the ContentPortraitVC is asked to remove the ContentModalDetailVC, nothing happens. The modal display stays put. What is going on?
When you use addChildViewController to add the ContentPortraitVC:
a. The ContentPortraitVC gets its parentViewController property set.
b. You then (as per the Apple documentation) have to manually display the ContentPortraitVC's view. If you follow the documentation you do this by adding it as a child of the ControllerVC's top level view.
The ContentPortraitVC then calls presentViewController to display ContentModalDetailVC.
a. This sets its presentingViewController property (in the debugger this is shown as the _parentModalViewController ivar -- note the ivar is different from the property), and sets the presentedModalViewController property of the ContentPortraitVC (who's ivar is _childModalViewcontroller).
b. Views wise, on iPhone, the ContentModalDetailVC's view will completely replace the views from ContentPortraitVC and ContainerVC, so only the modal view controller's view will be visible. (on iPad, it layers the new UI over the top, but as a sibling of the ControllerVC's view, which in turn is the parent of ContentPortraitVC's view).
So now, you transition from ContentPortraitVC to ContentLandscapeVC.
a. IOS does a bit of magic. It knows that the thing you are removing (ContentPortraitVC) has a presentedViewController currently active, so it changes its parent. It sets the value to nil on ContentPortraitVC, takes the child (the ContentModalDetailVC) and sets its parent to the new view (ContentLandscapeVC). So now the view controller that presented the modal view is no longer its presenting view controller. It is as if ContentLandscapeVC presented it in the first place!
b. In terms of views, you follow the Apple docs to change over the view from ContentPortraitVC to ContentLandscapeVC. But you are simply changing the subviews of ControllerVC's view. On iPhone, the modal view controller is still the only thing being displayed, so making the change doesn't do anything on screen. On iPad, it does (though you probably won't see it, as the modal view is usually full screen).
Now you come to dismiss the modal view. Presumably you do this in ContentPortraitVC, but it no longer has any reference to the thing it presented. So calling [self dismissViewController... does nothing, because ContentPortraitVC is no longer presenting anything, responsibility for that has been passed on to ContentLandscapeVC.
So that's what happens and why. Here's what to do about it.
You can rewire the delegate manually when you change from ContentPortraitVC to ContentLandscapeVC, so the latter is the one that tries to dismiss the modal controller.
You can have the modal controller dismiss itself with [self dismissModalControllerAnimated:YES completion:nil]. I'm going to ask and answer another question on why that works (how does IOS know which to dismiss?), if that seems strange.
You can have the ControllerVC be the one that pops up the modal view and be responsible for removing it.
If you inspect presentingViewController on ContentModalDetailVC, you will see that it is actually presented by ContainerVC and not ContentPortraitVC.
To fix this, you just need to set definesPresentationContext (or use the "Defines Context" checkbox in Interface Builder) on ContentPortraitVC.
This will tell ContentPortraitVC to handle the modal presentation instead of passing up the responder chain to the next view controller that defines presentation context (your root view controller by default).
You will probably want ContentLandscapeVC to define context as well to avoid the same issue.
With both child controllers defining their own presentation context, when ContainerVC decides to swap children, any modal modal will be removed from the new hierarchy along with the child that presented it. No need to do hacky things to try to dismiss before swapping :)
Edit: I should add that the view controller being presented must have its modalPresentationStyle Set to either currentContext or overCurrentContext,
I know this question is a bit open-ended but I'm trying to make it as specific as possible because I don't really know what a standard convention would be for this type of thing with iOS. I have been looking into implementing a login screen on my app, however I am having trouble figuring out the best way. I have three methods listed below, could anybody tell me if one of these is better or a more correct approach? (or if there is something that I totally missed).
The first approach - I initially have a navigation controller as my root controller with the login screen being the first view on the stack. Then when the user logs in, i just push the main UI to the stack. The user can then use the back button to return to the login screen. I know this technique works but then when re-launching the app, the user doesn't need to login again. I'm not sure should I just set up the stack the same way (login page first) and then push the main UI on top? Is that a common technique?
The next approach, I found here how to replace the root controller How to change RootViewController (in AppDelegate) from within CustomViewController? I like this idea better where I could just get rid of the login screen after login and add some type of button to bring it back on logout. Then during re-launch I can just skip adding the login screen altogether.
The third approach is perhaps overlaying the login on top of the main UI but I haven't found any code to do this. It also seems a little weird because my main UI might start firing messages that i wouldn't want to occur until after login so I'd have to account for that.
I would suggest you to have a root view controller with a blank view. This controller is set as a root view controller in the AppDelegate's applicationDidFinishLaunching: method.
Role of this root view controller would be to show the login screen through login view controller initially. Login view controller delegates to root view controller upon successful login to remove itself from root view and root view controller then set the next controller to be displayed.
This way you can manages multiple views if any before showing the main view through your root view controller.
There are different ways to display login view on top of root view.
1) Present a login view controller without animation.
2) Add login view as a subview on top of root view [Note: Before iOS 5, you don't get the rotation and view life cycle call backs and you should write your own code to pass the callbacks to the view added on top of root view. From iOS 5 onwards you have view containment concept using which you can maintain parent child relationship.]
Hope this helps.
We have a similar app. Our storyboard looks a little like a wheel.
We have a navigation controller as our root controller, which then goes to a view controller with a spinner on it. That controller handles the call to see if the user is logged in or not. It is connected to two different controllers.
If they are already logged in, it goes to the main view controller. If they haven't logged in, it goes to the login view controller. The login view controller will go back to initial view controller on success, and since they'll then be logged in, it goes to the main controller.
To fall back, we go all the way back to the initial view controller with the spinner on it.
You can hide the navigation bar on every view before the main one.
I always implement it with storyboard. Just add Storyboard ID to your login view controller, say Onboarding.
Then write something like this in application: didFinishLaunchingWithOptions:
if (![[NSUserDefaults standardUserDefaults] objectForKey:TRAIN_COMPLETE]) {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.window.rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"Onboarding"];
}
All our ViewController are subclassed from a custom subclass of uiviewcontroller. This allow us to make powerful enhancements on behavior, constraints, ...
Our super view controller class handle authentification by summoning a modal view on viewWillAppear if user is not logged in.
Works like a charm to handle disconnection and resuming from any point in the app.