从 UIButton 的类中获取当前的 UIViewController

Posted

技术标签:

【中文标题】从 UIButton 的类中获取当前的 UIViewController【英文标题】:Get current UIViewController from UIButton's class 【发布时间】:2014-08-05 17:46:34 【问题描述】:

我有自定义 UIButton,它通过协议以编程方式与 ViewController 方法交互(触发)。但是按钮的行为必须依赖于放置的 ViewController。我这样做是为了尽量减少 ViewControllers 本身的代码量,因为按钮必须保持不变并具有相同的功能(导航)。 在 UIButton 的自定义类中有什么方法可以获取它所在的 ViewController 吗?

【问题讨论】:

这不是你想做的。相反,将属性添加到按钮类。然后每个视图控制器可以适当地设置属性。该按钮不应该知道任何视图控制器的任何信息。 关键思想是根本不用VC写代码。在您的情况下,我必须重写 VC 类,但是,只重写一个类(因为只需要一次自定义行为)就可以了,问题就在这里:按钮被放置在情节提要上,除了协议之外没有任何编程连接。那么,如果我只有一个需要自定义行为的 VC,如何从 VC 端访问按钮? VC 可以通过插座或属性访问其视图。在 MVC 中,视图永远不应该知道它的控制器。 从这个角度来看,我的自定义 UIButton 是控制器还是严格来说是视图?它以编程方式创建和隐藏一些按钮。该按钮会触发相应 VC 上的操作。 【参考方案1】:

我会以特定方式遵循 @rmaddy 的建议,借鉴 SDK 的风格

// MyCutomButton.h
@protocol MyCustomButtonDatasource;

@interface MyCustomButton : UIButton
@property(weak,nonatomic) IBOutlet id<MyCustomButtonDatasource>datasource;
// etc
@end

@protocol MyCustomButtonDatasource <NSObject>
@optional
- (NSString *)howShouldIBehave:(MyCustomButton *)button;
@end

现在按钮可以在 IB 中设置它的数据源。包含它的视图控制器将需要一些额外的代码(抱歉,在好的设计中这是不可避免的)。他们将声明自己正在实现 MyCustomButtonDatasource。

当 MyCustomButton 需要根据其放置位置有条件地运行时,它可以询问其数据源...

// MyCustomButton.m

NSString *string = @"defaultBehavior";  // per @RichardTopchiy's suggestion
if ([self.datasource respondsToSelector:@selector(howShouldIBehave:)])
    string = [self.datasource howShouldIBehave:self];

// string is just made-up here, have it answer something simple (int, BOOL)
// that lets the button proceed with the right behavior.  Don't ask for
// anything that relies on specific knowledge of how MyCustomButton
// is implemented

编辑 - 要创建关系,如果您已将属性装饰为 IBOutlet(如上所示),您应该能够在 IB 中设置关系。将您的视图控制器声明为实现&lt;MyCustomButtonDatasource&gt;。选择您的自定义按钮,然后选择连接检查器,然后拖动到您的视图控制器。

或者,使按钮本身成为视图控制器中的 IBOutlet 属性,并在 viewDidLoad 中执行以下操作:

self.customButton.datasource = self;

最后一种方法是给你的按钮一个标签,比如 128,然后:

MyCustomButton *customButton = (MyCustomButton *)[self.view viewWithTag:128];
self.customButton.datasource = self;

【讨论】:

将方法包含为“可选”并仅在应使用非默认行为的 VC 上实现是一种好习惯吗? 还有一个问题,来自 VC 端 - 我应该如何将 howShouldIBehave 方法绑定到 ViewController?我需要创建一个新的 CustomButton 实例(我认为不需要)还是只是“抓住”现有按钮。我需要这个来设置委托。

以上是关于从 UIButton 的类中获取当前的 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

从不同的类更改 UIButton alpha

从脚本中的类中获取值

如何从具有父类引用的类中获取记录?

是否可以从为 getter-setter 方法创建的类中获取数据

从控制器的类中获取 MVC 控制器名称

从选定的不同类设置 UIButton