rai*_*ger 10 cocoa-touch objective-c
我是Objective C和Cocoa的新手.我只是不知道如何发送UIView的超级视图.我无法让它发挥作用.这是我到目前为止所尝试的:
在我的MainView中,我有一个名为resetDrawType的方法:
- (void) resetDrawType {
self.drawType = foo;
}
Run Code Online (Sandbox Code Playgroud)
同样在MainView中我创建一个子视图并将其添加到MainView:
mySubView *mySubView = [[mySubView alloc] initWithFrame:CGRectMake(foo, foo, foo, foo)];
[self addSubview:mySubView];
[mySubView release];
Run Code Online (Sandbox Code Playgroud)
然后当子视图完成其绘图时,我想将消息resetDrawType发送到其superview,即MainView.
我试过这个
[(MainView*)[self superview] resetDrawType];
Run Code Online (Sandbox Code Playgroud)
和
[(MainView*)self.superview resetDrawType];
Run Code Online (Sandbox Code Playgroud)
......什么都行不通.我了解了非正式协议,因此我将此代码添加到MainView.h中
@interface NSObject ( resetters )
- (void) resetDrawType;
@end
Run Code Online (Sandbox Code Playgroud)
但仍然没有.接下来我发现了这个选择器的东西并在子视图中尝试了这个:
if ([self.superview respondsToSelector:@selector(resetDrawType:)])
[self.superview performSelector:@selector(resetDrawType) withObject:nil];
Run Code Online (Sandbox Code Playgroud)
它也没用.我究竟做错了什么?谢谢你的帮助.
Ale*_*yne 11
你不应该有一个子视图告诉它的超级视图很多东西.您应该将superview作为视图类的委托.
// MainView
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...) delegate:self];
Run Code Online (Sandbox Code Playgroud)
然后将委托保存到声明的实例变量id delegate.完成绘图后:
// MyView
- (void)doDrawing {
drawStuff();
[delegate didFinishDrawingView:(MyView *)self]
}
Run Code Online (Sandbox Code Playgroud)
现在回到MainView中,实现此方法
- (void)didFinishDrawingView:(MyView *)aView;
Run Code Online (Sandbox Code Playgroud)
做你想做的事.
所有这一切的重点在于,应用程序边缘的小类(如小型子视图)不需要知道它们上面的大类是如何工作的.此设置允许视图向上传递链,但是使用传达其自身状态的消息而不是指示其他对象执行特定操作的消息.这就是Cocoa的结构方式,以便可以轻松地重用类,并且可以重新调整它们的事件,但是你需要它们.
您的超级视图应该知道子视图完成后要执行的操作.子视图应该让人们知道它已完成.
在子视图类的头文件中声明一个实例变量,如下所示:
id delegate;
Run Code Online (Sandbox Code Playgroud)
为您的子视图类编写一个initiailizer,如下所示:
- (id)initWithFrame:(CGRect)frame delegate:(id)aDelegate {
[super initWithFrame:frame];
delegate = aDelegate;
return self;
}
Run Code Online (Sandbox Code Playgroud)
现在你有了一个初始化程序,它将接受委托,保存该委托,然后允许你在其上调用方法.
首先,在Objective-C中,不需要强制转换为特定类来向其发送消息.你可以这样做;
[self.superview resetDrawType];
Run Code Online (Sandbox Code Playgroud)
提供父视图具有以下功能;
- (void) resetDrawType {
}
Run Code Online (Sandbox Code Playgroud)
那么这应该正常工作.没有必要使用非正式协议.
您的选择器测试也是错误的,因为它与"resetDrawType"函数的定义不匹配.@selector(resetDrawType :)测试名为"resetDrawType"的函数,它接受参数,而不是你的参数.
这是你如何测试上面的功能;
if ([self.superview respondsToSelector:@selector(resetDrawType)])
[self.superview performSelector:@selector(resetDrawType)];
Run Code Online (Sandbox Code Playgroud)
(而不是performSelector你也可以直接发送消息).
| 归档时间: |
|
| 查看次数: |
12163 次 |
| 最近记录: |