Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 502 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Get to UIViewController from UIView?

#1
Is there a built-in way to get from a `UIView` to its `UIViewController`? I know you can get from `UIViewController` to its `UIView` via `[self view]` but I was wondering if there is a reverse reference?
Reply

#2
There is no way.

What I do is pass the UIViewController pointer to the UIView (or an appropriate inheritance). I'm sorry I can't help with the IB approach to the problem because I don't believe in IB.

To answer the first commenter: sometimes you do need to know who called you because it determines what you can do. For example with a database you might have read access only or read/write ...
Reply

#3
Even though this can technically be solved as *pgb* recommends, IMHO, this is a design flaw. The view should not need to be aware of the controller.
Reply

#4
Don't forget that you can get access to the root view controller for the window that the view is a subview of. From there, if you are e.g. using a navigation view controller and want to push a new view onto it:

[[[[self window] rootViewController] navigationController] pushViewController:newController animated:YES];

You will need to set up the rootViewController property of the window properly first, however. Do this when you first create the controller e.g. in your app delegate:

-(void) applicationDidFinishLaunching:(UIApplication *)application {
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RootViewController *controller = [[YourRootViewController] alloc] init];
[window setRootViewController: controller];
navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[controller release];
[window addSubview:[[self navigationController] view]];
[window makeKeyAndVisible];
}



Reply

#5
While these answers are technically correct, including Ushox, I think the *approved* way is to implement a new protocol or re-use an existing one. A protocol insulates the observer from the observed, sort of like putting a mail slot in between them. In effect, that is what Gabriel does via the pushViewController method invocation; the view "knows" that it is proper protocol to politely ask your navigationController to push a view, since the viewController conforms to the navigationController protocol. While you can create your own protocol, just using Gabriel's example and re-using the UINavigationController protocol is just fine.
Reply

#6
My solution would probably be considered kind of bogus but I had a similar situation as mayoneez (I wanted to switch views in response to a gesture in an EAGLView), and I got the EAGL's view controller this way:

EAGLViewController *vc = ((EAGLAppDelegate*)[[UIApplication sharedApplication] delegate]).viewController;
Reply

#7
I think there is a case when the observed needs to inform the observer.

I see a similar problem where the UIView in a UIViewController is responding to a situation and it needs to first tell its parent view controller to hide the back button and then upon completion tell the parent view controller that it needs to pop itself off the stack.

I have been trying this with delegates with no success.

I don't understand why this should be a bad idea?
Reply

#8
I would suggest a more lightweight approach for traversing the complete responder chain without having to add a category on UIView:

@implementation MyUIViewSubclass

- (UIViewController *)viewController {
UIResponder *responder = self;
while (![responder isKindOfClass:[UIViewController class]]) {
responder = [responder nextResponder];
if (nil == responder) {
break;
}
}
return (UIViewController *)responder;
}

@end
Reply

#9
I don't think it's "bad" idea to find out who is the view controller for some cases. What could be a bad idea is to save the reference to this controller as it could change just as superviews change.
In my case I have a getter that traverses the responder chain.

//.h

@property (nonatomic, readonly) UIViewController * viewController;

//.m

- (UIViewController *)viewController
{
for (UIResponder * nextResponder = self.nextResponder;
nextResponder;
nextResponder = nextResponder.nextResponder)
{
if ([nextResponder isKindOfClass:[UIViewController class]])
return (UIViewController *)nextResponder;
}

// Not found
NSLog(@"%@ doesn't seem to have a viewController". self);
return nil;
}

Reply

#10
Another easy way is to have your own view class and add a property of the view controller in the view class. Usually the view controller creates the view and that is where the controller can set itself to the property. Basically it is instead of searching around (with a bit of hacking) for the controller, having the controller to set itself to the view - this is simple but makes sense because it is the controller that "controls" the view.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through