Displaying UIAlertController on top most UIViewController - objective-c

I am creating an alert using UIAlertController and I would like the alert to display on whichever view controller is currently being displayed. This application has about 30 different view controllers and I need the alert to display on whichever view is currently being displayed. Does anyone have a suggestion to do this in the easiest manner.
I am using NSTimer to call a function on one of the views every 30 seconds, looking for a response from a SOAP service. I would like to be able to know which view is currently in use and display the alert if there is a response from my SOAP service.

You probably want the code that is polling for the SOAP service to generate a broadcast notification, and each of your viewControllers would be observing for that notification. It's possible that all of the viewControllers would get the notification at the same time, but I suspect that only the foreground viewController could act on it (or, you need some way for the viewController to know that it is the active viewController and if not the active one, ignore the notification). Or, you could do the addObserver when the viewController appears, and remove the observer when the viewController disappears.
See this post:
Send and receive messages through NSNotificationCenter in Objective-C?

self.window?.rootViewController?.navigationController?.topViewController return top view controller on the stack

Related

UIKeyboardWillShowNotification - iOS8 vs iOS7

With iOS8, I noticed that a view controller was no longer receiving a UIKeyboardWillSHowNotification, when it previously was with iOS7.
Here's the scenario:
1.) View Controller A is displaying a keyboard, and pushes View Controller B without resigning first responder
2.) View Controller B has a control that becomes first responder during its viewDidLoad call, while it's being created by VCA, before it's pushed onto the nav controller
3.) If VC A is NOT displaying a keyboard when pushing B, the notifications work fine. However, if A is still editing when pushing B, then B does not get a keyboard will show notification.
Without the keyboard notification, VC B is not resizing / repositioning and does not look right.
The workaround I'm using until I find a solution is to do the following from any view controllers that might be editing when pushing another view controller that might be editing:
i.e., before pushing another view controller, be sure to call:
[self.view endEditing:YES];
While it works, it doesn't seem good that the view controller (B) can be 'broken' by the state of the app prior to displaying it.
Question: Am I doing something wrong here?
As far as I can tell, one of 3 things are possible:
A.) I should be getting the notifications, but I'm not b/c I'm doing something wrong
B.) I should be getting the notifications, but I'm not b/c of a bug
C.) I can't rely on always getting the notifications...But if I don't get the notifications in VC B when it appears, I need to be able to get the keyboard dimensions of the displayed keyboard without relying on the keyboard notification info. All the apple docs say to use the notifications though (as far as I can find).... which points back to options A.) or B.).
I can create and upload sample code later tonight / early tomorrow to try and isolate / for you all to test/reproduce to see what I'm doing.
I can see the same issue with iOS8 / xCode6 (works with iOS7 and xCode5). In my case, I'm observing a systemStatus property on the model in my AppDelegate so as to log the user out and bring the user back to the login screen when the user logs out from anywhere in the app. I'm doing that by setting the window.rootViewController to the loginViewController in my App Delegate observeValueForKeyPath: method.
This works fine on iOS7 / xCode5 but on iOS8 / xCode6, I loose the keyboard in the way. Looks like my loginViewController might be registering for keyboard notifications (in its ViewWillAppear method) before the window's rootViewController switch is complete (in iOS8) thus registering to the old window's notification center...
I moved the registration for keyboard notifications to the ViewDidAppear: method instead and that seems to fix it but somehow this seems to be called twice for some reason.

Send data back to rootviewcontroller before a popToRootViewController method call?

What is the best way to send data back to the root view controller before calling the popToRootViewControllerAnimated method? I am trying to signal to the rootviewcontroller that the current viewcontroller no longer exists and keep a record of what viewcontroller has been pushed thru segue.
You mustn't wait until the current view controller "no longer exists". While the current view controller does exist, the root view controller is the current view controller's navigationController.viewControllers[0]. So you have the reference you need to send a message from this one to that one. Just cast to the root view controller's class and now you can call any public method in the root view controller, e.g.
MyRootViewController* rvc = (MyRootViewController*)(self.navigationController.viewControllers[0]);
rvc.coolData = myCoolData;
There are two basic ways to do this: 1) with an NSNotification message or 2) with a delegate call. There are plenty of tutorials on how to code both. I wrote a small delegate tutorial as an answer to this question: Back button in iphone app and you can find a great NSNotification tutorial here: Send and receive messages through NSNotificationCenter in Objective-C?
You can subclass UINavigationController and override the necessary methods to track your array. I would recommend keeping a uniqued set of titles for each view controller popped off the stack. As for signaling to the current view controller that the previous view controller doesn't exist, that's what -viewWillAppear is for. If you need finer-grain control, create a protocol for your View Controller instances to conform to that the navigation controller calls out to when it pops one or more of them off the stack.

How to stop a ViewController

I have an application that can be started from the web via a URI scheme, that I have registered in my app. Depending on the URI, I open different view controllers (by setting the rootViewController in AppDelegate). Each view controller asynchronously gets some initialization data from a server upon initialization.
My problem is: If my server responds slowly and I go out of the application and enter the application again (causing a new view controller to open), then the first view controller still exists in the background and receive the server response for the request that it sent. This can cause an alert to be shown by the first view controller, even though that view controller is no longer in focus.
I could fix this by setting a flag in the viewDidDisappear: method. But this kind of handling messes up the code, and it would be much nicer if I could somehow stop the view controller from the AppDelegate. Or at least ensure that it only displays an alert view if it is in the foreground. Is there any way to do one of these things?
I found a possible solution in another SO question
if (viewController.isViewLoaded && viewController.view.window) {
// present alert view
}
This avoids the flags, but it still needs to be spread out where alert views are presented.

UIActionSheet always on top of view

I have implemented a Pin-Lock viewController such that every time app becomes active, the Pass-Lock view is shown.
-(void)applicationDidBecomeActive:(UIApplication *)application
{
//--- showing Pass-Lock View
}
But,while resigningActive,if any UIActionSheet was displaying(Any where in the App). On resuming the App the Pass-Lock view is shown along with the UIActionSheet.
Till now I have implemented one "UIApplicationWillResignActiveNotification", but this is particular to one view. So I have to implement is all over the app.
Can any one suggest better solution?
You don't need to use notifications for this. because, We have already some delegate methods in application delegate class. These delegates will call according to the application status. This will work for all over the app. So that, you can continue with those delegates.

Is there a way to change Views in iOS without using UINavigationController?

I have a login page at the beginning of my app that I do not want on the view stack. Is there a way to load my first post-login view after the login without using UINavigatorController?
Is there a better way to be doing this? Should I be using 2 UINavigationControllers? Is there a way to change the RootViewController for a UINavigationController?
Yes, you can change root controller of window. Set window's property rootViewController to new controller and you're done. Don't forget though that first controller (one you are removing) will not receive viewWillDisappear: and viewDidDisappear: messages. Send them yourself before switching controllers if you're interested in them.
You might also look at UIViewController#presentViewController