Given a view, how do I get its viewController?


Given a view, how do I get its viewController?



I have a pointer to a UIView. How do I access its UIViewController? [self superview] is another UIView, but not the UIViewController, right?




What is the maximum length of NSString? Alternative to NSString - iPhone

1:



Apple Push Notification Service
Yes, the superview is the view that contains your view.


App crashes on fast exit+restart
Your view shouldn't know which exactly is its view controller, because that would break MVC principles..
Different ways to initialize singletons
The controller, on the other hand, knows which view it's responsible for (self.view = myView), and usually, this view delegates methods/events for handling to the controller..
Monotouch iPhone Landscape Mode
Typically, instead of a pointer to your view, you should have a pointer to your controller, which in turn can either execute some controlling logic, or pass something to its view..
How can i restrict Texting in iPhone if it is in Motion of 10MPH?


Using NSUserDefaults from javascript webapp


Exception: unrecognized selector … when trying to push a view controller on Navigation stack

2:


From the UIResponder documentation for nextResponder:.
The UIResponder class does not store or set the next responder automatically, instead returning nil by default.

Subclasses must override this method to set the next responder.

UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t); UIViewController implements the method by returning its view’s superview; UIWindow returns the application object, and UIApplication returns nil..
So, if you recurse a view’s nextResponder until it is of type UIViewController, then you have any view’s parent viewController.. Note that it still may not have a parent view controller.

But only if the view has not part of a viewController’s view’s view hierarchy.. Swift extension:.
extension UIView {     var parentViewController: UIViewController? {         var parentResponder: UIResponder? = self         while parentResponder != nil {             parentResponder = parentResponder!.nextResponder()             if let viewController = parentResponder as? UIViewController {                 return viewController             }         }         return nil     } } 
Objective-C category:.
@interface UIView (mxcl) - (UIViewController *)parentViewController; @end  @implementation UIView (mxcl) - (UIViewController *)parentViewController {     UIResponder *responder = self;     while ([responder isKindOfClass:[UIView class]])         responder = [responder nextResponder];     return (UIViewController *)responder; } @end 
This macro avoids category pollution:.
#define UIViewParentController(__view) ({ \     UIResponder *__responder = __view; \     while ([__responder isKindOfClass:[UIView class]]) \         __responder = [__responder nextResponder]; \     (UIViewController *)__responder; \ }) 


3:


For debug purposes only, you can call _viewDelegate on views to get their view controllers.

This is private API, so not safe for App Store, but for debugging it is useful.. Other useful methods:.
  • _viewControllerForAncestor - get the first controller that manages a view in the superview chain.

    (thanks n00neimp0rtant)
  • _rootAncestorViewController - get the ancestor controller whose view hierarchy is set in the window currently.


4:


To get reference to UIViewController having UIView, you could make extension of UIResponder (which is super class for UIView and UIViewController), which allows to go up through the responder chain and thus reaching UIViewController (otherwise returning nil)..
extension UIResponder {     func getParentViewController() -> UIViewController? {         if self.nextResponder() is UIViewController {             return self.nextResponder() as? UIViewController         } else {             if self.nextResponder() != nil {                 return (self.nextResponder()!).getParentViewController()             }             else {return nil}         }     } }  let vc = UIViewController() let view = UIView() vc.view.addSubview(view) view.getParentViewController() //provide reference to vc 


5:


If you are not familiar with the code and you want to find ViewController coresponding to given view, then you can try:.
  1. Run app in debug
  2. Navigate to screen
  3. Start View inspector
  4. Grab the View you want to find (or a child view even better)
  5. From the right pane get the address (e.g.

    0x7fe523bd3000)
  6. In debug console start writing commands:
     po (UIView *)0x7fe523bd3000     po [(UIView *)0x7fe523bd3000 nextResponder]     po [[(UIView *)0x7fe523bd3000 nextResponder] nextResponder]     po [[[(UIView *)0x7fe523bd3000 nextResponder] nextResponder] nextResponder]     ... 

In most cases you will get UIView, but from time to time there will be UIViewController based class..


6:


I think you can propagate the tap to the view controller and let it handle it.

This is more acceptable approach.

As for accessing a view controller from its view, you should maintain a reference to a view controller, since there is no another way.

See this thread, it might help: Accessing view controller from a view.


7:


If you set a breakpoint, you can paste this into the debugger to print the view hierarchy:.
po [[UIWindow keyWindow] recursiveDescription] 
You should be able to find your view's parent somewhere in that mess :).


8:


What if you associate a value with a view using setValue, then the view can query that value to refer to whatever object it needs? Similar to setting the data property on a Win32 HWND e.g..



85 out of 100 based on 75 user ratings 775 reviews