2

我的问题是跟随

我有一个 UIViewController 子类,它包含一个 UISegmentedController 和四个我在界面构建器中布置的表格视图。

@interface MultiTableHoldingView : UIViewController{

}

@property (strong, nonatomic) IBOutlet DataTV *dsDataTV;
@property (strong, nonatomic) IBOutlet EnviroTV *dsEnvironmentTV;
@property (strong, nonatomic) IBOutlet LocationTV *dsLocationTV;
@property (strong, nonatomic) IBOutlet Note_AnimalTV *dsNoteAnimal;

@property (strong, nonatomic) IBOutlet UISegmentedControl *diveElementSegmentController;

@property (strong, nonatomic) DiveSite* currentSite;

- (IBAction)diveElementSegmentControllerDidChange:(UISegmentedControl *)sender;

-(void) setFreshWaterColor;
-(void) setSaltwaterColor;

@end

setFreshWaterColor 和 setSaltWaterColour 只是设置 MultiTableHoldingView 实例 UIView 及其包含的四个 tableview 的背景颜色属性。当从 MultiTableHoldingView 的 viewDidLoad 方法调用时,这两种方法都可以正常工作。这是其中之一

-(void) setSaltwaterColor{

    DLog(@"in set salt water colour");
    self.view.backgroundColor= SaltWaterColor;
    _dsLocationTV.backgroundColor=SaltWaterColor;
    _dsDataTV.backgroundColor=SaltWaterColor;
    _dsEnvironmentTV.backgroundColor=SaltWaterColor;
    _dsNoteAnimal.backgroundColor=SaltWaterColor;

}

另一个是相同的,除了设置为 FreshWaterColor - 两者都是我设置的#define。

我使用分段控制器来打开和关闭各种表格视图的隐藏属性。一切都很好,很简单。表格视图正在提取他们的数据。工作正常。

在其中一个表视图上选择我的表视图单元格之一时,我想更改我的表视图(实际上是我的所有表视图)和作为超级视图的 UIView 的背景颜色

self.superview.backgroundColor = FreshWaterColor;

可以很好地返回并更改 MultiTableHoldingView 视图背景属性的实例,但我想调用 MultiTableHoldingView 的 setFreshWaterColor 和 setSaltwaterColor 方法的实例。

我已将 MultiTableHoldingViews 标头导入相关的 tableview (EnviroTV),因此它知道它的 superviews 方法。但是,如果我尝试在 self.superview 上调用这两种方法中的任何一种,这些方法都不会显示,并且如果我完整输入它们,我会收到以下错误

“UIView”没有可见界面显示选择器“setFreshWaterColor”

所以我检查了superview是什么类型的对象,它是一个“superview UIViewControllerWrapperView的类”

我搜索这个和它显然“

这是框架使用的私有视图。你不应该修改它或任何东西。”

我显然在这里遗漏了一些东西 - 我应该如何在 MultiTableHoldingView 的实例上调用该方法?

提前致谢

西蒙

Doh - 正如 danypata 在评论中提到的那样,它只是代表 - 我已经在下面发布了我是如何做到这一点的答案。试图尽可能清楚地说明委派的工作方式

4

1 回答 1

3

解决方案

第一步——在编码之前多睡一会儿。

这确实是基本的objective-c 东西——我只是在切线,寻找其他方法来做这件事,被我一路上发现的 UIViewControllerWrapperView 弄糊涂了。

正如 danypata 在评论中正确建议的那样,解决方案是使用委托——Objective-C 中的一种常见设计模式——就像你做的那样,例如,当你使用另一个类来提供 tableview 数据时

由于我今天浪费了很多时间,因此我将尝试为其他相对新手或休息日不思考的人弄清楚“如何”。

就我而言,我将其设置如下

在我的子视图类的接口文件中 - EnviroTV.h - 我在 @interface 声明之前定义了以下协议

@protocol EnviroTVProtocol <NSObject>


-(void) setFreshWaterColor;
-(void) setSaltwaterColor;


@end

然后在同一个文件的@interface 部分中,我添加了一个 id 类型的属性,它必须符合我刚刚声明的协议。

@property (nonatomic, strong ) id<EnviroTVProtocol> colorChangeDelegate;

您将类型设置为 id - 一个通用对象 - 因为您真的不在乎什么样的对象将充当您的委托,只是它实现了您需要它运行的方法。当一个对象声明自己要实现一个协议时,它只是承诺实现协议所需的方法

所以,当我想在我调用的 superviews 类上运行方法时

[self.colorChangeDelegate setFreshWaterColor];

或者

[self.colorChangeDelegate setSaltWaterColor];

委托模式的最后一部分是进入将成为委托的类(在本例中是我的 MultiTableHoldingView 类)并声明它符合协议

我在 MultiTableHoldingView.h 文件中执行此操作

更改此行:

@interface MultiTableHoldingView : UIViewController

进入这一行:

@interface MultiTableHoldingView : UIViewController <EnviroTVProtocol>

表示此类承诺实现 EnviroTVProtocol 的所有必需方法。

幸运的是,我已经编写了这两种方法。所以当我编译它运行正确

新手——不要害怕授权——它很棒而且不像你最初想象的那么复杂

同时,如果有人可以解释 UIViewControllerWrapperView 是什么......

于 2013-06-12T22:33:06.970 回答