viewDidGetCoveredUpByModalPresentationFormSheet? - ios

I have an app that has different integrations such as Evernote and Dropbox. When the user authenticates them, a UIViewController presents the authentication view as a UIModalPresentationFormSheet. This doesn't trigger viewDidDisappear for my view which makes sense since it doesn't disappear.
Is there another method I can implement that will be notified?

I assume you want to know when the modal view as been presented? Assuming you are using presentViewController:animated:completion , you can use the completion handler to know when the viewcontrollers view has been presented Here is a ref

Related

'Minimize' a ViewController that user can access at any time anywhere in the app

I need some hints or suggestions on an issue.
What I want to do is to 'Minimize' a UIViewController like the 'message circles' in old facebook messages. So that the user can continue using the app and just move the circle to anywhere on the screen and then tap it to open it up and continue working from there.
The minimized UIViewController is suppose to be a UIWebView and I want the user to be able to continue working from whatever state the webpage was in.
I know one is suppose to add code here but I more want some pointers on where to start and how to think or possibly some suggested codesnippets or links.
Hope someone can help me out.
Thanks
edit: Thanks Moti. Ok so I will Not be using storyboard but do do everything programmatically.
I will have it not fully hidden but 'minimized' as an ontop circle to be accessed to just by tapping it anywhere from in the app.
Trick14, I will have a check. tnx
Make a Base View Controller which is inherited by every ViewController in your app. Declare the functions in it. And you can directly access these functions in any of your base class. Or simply hide or show your view anywhere in your app.
If its part of navigation controller you can keep strong reference to it somewhere, so when you pop it out it will stay alive. And when you need it you can push it again.
If you can describe some more details regarding how you show/hide and if its part of storyboard or built in runtime, the community will be able to be more specific regarding solutions.
If you look into UIViewController you will see
addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
You can play around with those to achieve what you need, for example when you detect that the "overlay" controller removed from parent view controller you could push it back in the method didMoveToParentViewController: of the the other controller.
Yes, there is some management to be done, but it is possible.
I will try to make some working example with dummy views.

Distinguishing the user action causing a view controller to be pushed

I'm subclassing UINavigationController and want to in order to add the ability to add previously popped view controllers back onto the stack, akin to a forward button in a web browser.
When the user presses a button, I want to add the most recently popped off view controller back onto the stack. I do this by getting the view controller at the top of my custom stack, and calling pushViewController:animated: with it.
In the case where taps on a table view cell or something to go forward a new way into the view hierarchy, I want to clear my "popped view controllers" stack. Similar to how if the user clicks on a new link in a web browser the "forward" history is cleared.
This is where my issue lies. I don't know how to differentiate between when I call pushViewController:animated: in order to restore a view controller, and when the user taps a cell to push one. In the latter case, I want to clear my stack, but in the former I don't want to.
I can't figure out what to do here. In a perfect world pushViewController:animated: would have userOptions: parameter or something on it that would allow me to distinguish between how it's being used, but unfortunately that parameter doesn't exist.
Such an issue must come up rather frequently. How would I deal with it in this case? How would I differentiate between the circumstances in which the method is being called?
If I follow you correctly one common approach to doing this is:
Your "goForward" method should call your superclass' pushViewController:animated:
Override pushViewController:animated: to call both your superclass' pushViewController:animated: and your "clearStack" method.
It seems to me that you need two different methods in your subclass. One for the case where you want to restore a view controller, and one where you want to clear the stack. Both will perform some custom logic and call pushViewController:animated: on super.

Showing master view on some pages and preventing the user from hiding it

I have an iPad app with a UISplitviewController set as the root view controller of UIWindow. The master view controller (i.e. the view controller of the left view) is the UISplitViewController's delegate with the delegate method shouldHideViewController returns YES, this means when the app first launches the left view will be hidden and can be shown (and hidden) by the user gesture, i want to show the master view when i navigate to detail pages and prevent the user from hiding it using the gesture, i've tried to call shouldHideViewController method on the delegate to let it returns NO the second time it got called but this time it has no effect, the master view keeps hidden in detail pages and can be shown with the user gesture.
any ideas to achieve showing of the master view with this scenario would be highly appreciated.
This may only be a partial answer because I'm not sure what you mean that you call shouldHideViewController method on the delegate. My understanding is that only the UISplitView should call this method. If you call it, then it will not effect the UISplitView, because it wasn't what made the call. In other words, the delegate method is used by UISplitView to get some information (and allow you a place to do additional things to other stuff) but it is not used as a way to tell the UISplitView what to perform.
Having said that, at least for the gesture activation/deactivation, I would think that in splitViewController:shouldHideViewController:inOrientation: you could do something like
[svc setPresentsWithGesture:NO];
I don't see any way to programmatically tell the UISplitViewController to display or hide the master view controller because the delegate only tells it if it should proceed in presenting or hiding the master when it is going to try and do that. It does seem like there should be a way to do this though.

My iOS app complains about two-staged rotation but I'm not using it

I have to support down to iOS 4.3.
My app outputs in the console :
Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
As far as I know I'm not using two-staged rotation. I just have this method in my view controllers :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
What else should I check in order to fix that?
Edit:
More precisions: my app uses a UITabbarController subclass. When the app starts, it checks if a user is logged in and then initiates the controllers of the tabbar controller if it's the case. If there's no user logged in, a modal view is presented (from the tabbar controller) the prompt the user to login and the controllers of the tabbar controller aren't initialized (yet). The "two-staged rotation" error is shown only at that moment and the rotation doesn't work.
So to summarize, the problem happens in that situation:
The rootViewController of the main window is the tabbar controller
The tabbar controller is empty (there are no view controller in the tabs and there's no tab)
A view controller is modally presented from the tabbar controller
OK I found a solution.
It seems like the presented modal view won't rotate until the viewControllers property of the UITabBarController is initialized. Since the concerned modal view is actually for login, I don't want to display anything behind it until the user is logged in because the views intended to be hold by the tabbar controller depend on the fact that a user is logged in.
So now just before presenting the modal view, I initialize the tabbar controller with a single, empty UIViewController and I remove it when the modal view is dismissed (i.e. a user logged in).
Perhaps it seems like a hack but it works well. And even if I don't understand why, it doesn't seem completely illogical that the tabbar controller doesn't behave like we want until it is fully initialized.
If someone has a better solution or explanation, feel free to comment :)
There aren't many posts regarding this error, so I'll admit my own shortcomings for the benefit of the next person so focused on the trees they might miss the forest. I found a missing
[super viewWillAppear:animated];
call inside my sub.

Design patterns for handling UILocalNotifications (how to know where user is within branching app)

I have an app which uses UILocalNotifications (though the question would also be relevant to PushNotifications). When the user receives a local notification, depending on the state of the app and the choice they make in the notification alert, I want to present a specific viewController. The issue is they may currently be in a "pushed" viewController through a segue or in a modal ViewController and I am not currently tracking where the user is within the possible branches.
I am wondering if there is any sort of design pattern or standard way of handling a mixed presentation mode app like this? Particularly if there is any built-in way to determine which is/are the active ViewController(s) without my having to setup a breadcrumb system. This would matter, for example, if the user is already viewing the viewController to be called as a result of the localNotification.
I realize my need/explanation is a little muddled. I'll edit and update this if anyone needs more info.
OK - I think I have a solution through the Apple docs View Controller Programming Guide for iOS: Presenting View Controllers from Other View Controllers
Each view controller in a chain of presented view controllers has
pointers to the other objects surrounding it in the chain. In other
words, a presented view controller that presents another view
controller has valid objects in both its presentingViewController and
presentingViewController properties. You can use these relationships
to trace through the chain of view controllers as needed. For example,
if the user cancels the current operation, you can remove all objects
in the chain by dismissing the first presented view controller. In
other words, dismissing a view controller dismisses not only that view
controller but also any view controllers it presented.
So I can cancel any chain of modal viewControllers by dismissing the first modal viewController in the chain.
I can determine if there is currently a modal viewController being presented using:
self.window.rootViewController.presentedViewController
If the property is null then there no modal viewController is currently being presented. And for completeness (hackishness..) I can test is the presentedViewController has a presentedViewController, etc.:
self.window.rootViewController.presentedViewController.presentedViewController

Resources