I am new to Objective C and Cocoa. I just don't get it how to message the superview of an UIView. I can't get it work. Here is what i tried so far:
In my MainView i have a method named resetDrawType:
- (void) resetDrawType {
self.drawType = foo;
}
Also in the MainView i create a subview and add it to MainView:
mySubView *mySubView = [[mySubView alloc] initWithFrame:CGRectMake(foo, foo, foo, foo)];
[self addSubview:mySubView];
[mySubView release];
Then when the subview finished its drawing i want to send the message resetDrawType to its superview, which is the MainView.
I tried this
[(MainView*)[self superview] resetDrawType];
and
[(MainView*)self.superview resetDrawType];
…what didn't work. I learned about Informal Protocols so i added this code to MainView.h
@interface NSObject ( resetters )
- (void) resetDrawType;
@end
But still nothing. Next i found out about this selector thing and tried this in the subview:
if ([self.superview respondsToSelector:@selector(resetDrawType:)])
[self.superview performSelector:@selector(resetDrawType) withObject:nil];
It also didn't work. What am I doing wrong? Thanks for your help.
You shouldn't have a subviews tell its superview much of anything. You should make the superview a delegate of your view class.
// MainView
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...) delegate:self];
Then save the delegate to an instance variable declared by id delegate
. When you finish drawing:
// MyView
- (void)doDrawing {
drawStuff();
[delegate didFinishDrawingView:(MyView *)self]
}
Now back in your MainView, implement this method
- (void)didFinishDrawingView:(MyView *)aView;
to do what you want.
The point of all this is so that the small classes at the fringe of your app (like a small subview) shouldn't need to know how the large classes above them work. This setup allows the view to communicate up the chain, but with a message that conveys its own status instead of a message that instructs other object to do something specific. This is the way Cocoa is structured so that classes can be easily reused and their events can be repurposed however you need them to be.
Your superview should know what to do when its subview finishes. The subview should just let people know its finished.
Declare an instance variable in your subview class's header like this:
id delegate;
Write an initiailizer for your subview class that looks like this:
- (id)initWithFrame:(CGRect)frame delegate:(id)aDelegate {
[super initWithFrame:frame];
delegate = aDelegate;
return self;
}
Now you have an initializer that will accept a delegate, saves that delegate, and allows you to then call methods on it.
Well firstly in Objective-C there's no need to cast to a specific class to send it a message. E.g you can just do;
[self.superview resetDrawType];
Providing the parent view has the following function;
- (void) resetDrawType {
}
Then this should work correctly. There's no need to use informal protocols.
Also your selector testing is wrong because it does not match the definition of the "resetDrawType" function. @selector(resetDrawType:) tests for a function named "resetDrawType" that takes on parameter, which yours does not.
This is how you would test for the function above;
if ([self.superview respondsToSelector:@selector(resetDrawType)])
[self.superview performSelector:@selector(resetDrawType)];
(Instead of performSelector you could also send the message directly).
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