I have created an UIViewController sub class which can either be pushed in a navigation stack of a UINavigationController or presented(modally) from any UIViewController. I need to identify whether my view controller is presented, if it is presented I need to add a toolbar with a close button at the top of the view controller. (else if it is pushed in navigation stack then the default close button will get added, by using that the user can go back.)
In all the available versions say 4.3, 5.0, till 6.0, from inside an UIViewController sub class, Can I assume that the view controller is presented(modally) if the following condition is satisfied.
if(self.parentViewController == nil || self.navigationController == nil)
The view's window property is non-nil if a view is currently visible, so check the main view in the view controller: Invoking the view method causes the view to load (if it is not loaded) which is unnecessary and may be undesirable. It would be better to check first to see if it is already loaded.
If you need a quick way to get hold of a view inside a complicated view hierarchy, you're looking for viewWithTag() – give it the tag to find and a view to search from, and this method will search all subviews, and all sub-subviews, and so on, until it finds a view with the matching tag number.
Both are used for different purpose. A UIViewController class manages a ViewContoller which is responsible for actions that happen within that View controller. This class is aware of actions that happen on view controller, like ViewDidLoad, ViewWillApper, ViewDidAppear, ViewWillDisapper, ViewDidDisapper.
A UIViewController is an object which manages the view hierarchy of the UIKit application. The UIViewController defines the shared behavior and properties for all types of ViewController that are used in the iOS application. The UIViewController class inherits the UIResponder class.
With iOS 5, UIViewController gained a readonly property named presentingViewController
, that replaces the older semantics of parentViewController
(which now describes containment). This property can be used when a view controller needs to get at the view controller that’s presenting it — note: this will often be something else than what you’d expect, if you’re new to the API!
In addition, the isBeingPresented
property had been introduced to pretty much solve the class of situations you’re currently in. Check for this property in your view controller’s viewWillAppear:
.
I overread that you seem to target iOS 4.3 as well:
In that case, you need to guard the call to isBeingPresented
with an if ([self respondsToSelector:…])
you can then in the else
block check for whether the parentViewController is not nil.
Another approach to backwards compatibility might be to override +resolveInstanceMethod:
to add an implementation for -isBeingPresented
at runtime. This will leave your calling sites clean, and you’d get rid of runtime-magic as soon as you let go of ancient iOS support ;-)
Note, though, that there are edge cases to this, and you initial approach as well, when running on iOS <5:
The view controller can be presented contained in any other view controller—including navigation controllers. When that last case happens, you’re out of luck: parentViewController
will be nil
, while navigationController
will not. You can try to add gobs of unwieldy code to mitigate this limitation in older iOSes…or you could just let it go.
I use the this code to check whether the UIViewController is presented.
if (uiviewcontroller.presentingViewController != nil) { // do something }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With