在其View中从UIViewController触发一个方法

我有一个UIViewController与其包含UIButton UIView 。 我想触发button单击事件UIViewController的方法。
保持UIViewController引用似乎不是一个好主意,像下面的链接说: 从UIView获取UIViewController?

所以我想用一个委托来实现这个。 任何暗示如何实现这一点?

你可以做这样的事情

CustomView.h

 #import <UIKit/UIKit.h> @protocol CustomViewDelegate <NSObject> -(void)didButtonPressed; @end @interface CustomView : UIView @property (assign) id<CustomViewDelegate> delegate; @end 

CustomView.m

 #import "CustomView.h" @implementation CustomView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = [UIColor whiteColor]; //[self addSubview:titleLbl]; UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = CGRectMake(100, 100, 100, 50); [button addTarget:self.delegate action:@selector(didButtonPressed) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"pressMe" forState:UIControlStateNormal]; [self addSubview:button]; } return self; } 

在您的ViewController.m

 -(void)loadView { [super loadView]; CustomView *view = [[CustomView alloc]initWithFrame:self.view.bounds]; view.delegate = self; [self.view addSubview:view]; } 

我想你会期望一些更基本的东西,然后通过一些button动作到控制器。 在模型/视图/控制器协作的情况下,我总是遵循MVC模式。 它解决了你的问题和其他许多问题。 我想分享我的经验。

  1. 从视图和模型分离控制器:不要把所有的“业务逻辑”放到视图相关的类中; 这使得代码非常不可用。 让控制器类来承载这个代码,但是确保控制器类不要对演示文稿做太多的假设。
  2. 使用@optional定义callbackAPI,如果不是所有的方法都是必需的,则使用@optional
  3. 对于视图定义协议,如<view class name>Protocol (例如NewsViewProtocol)。 对于控制器像<view class name>Delegate (例如NewsViewDelegate)和数据源如<view class name>DataSource (例如NewsViewDataSource)定义委托。 将所有这些@protocols保存在一个名为<view class name>Protocol.h单独文件中(例如NewsViewProtocol.h)

简短的例子:

NewsView.h的内容

 // // NewsView.h @interface NewsView : UIView <NewsViewProtocol> { @protected NSObject* delegate_; NSObject* dataSource_; } @end 

NewsController.h和.m的内容

 // // NewsController.h @interface NewsController : UIViewController <NewsViewDataSource, NewsViewDelegate> { } @property (nonatomic, weak) UIView<NewsViewProtocol>* customView; @end @implementation NewsController - (void)viewDidLoad { [super viewDidLoad]; self.customView = (UIView<NewsViewProtocol>*)self.view; [self.customView setDelegate:self]; [self.customView setDataSource:self]; } @end 

NewsViewProtocol.h的内容

 // // NewsViewProtocol.h @protocol NewsViewProtocol; @protocol NewsViewDelegate<NSObject> @optional - (void)someAction; - (void)newsView:(UIView<NewsViewProtocol>*)newsView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; @end @protocol NewsViewDataSource<NSObject> @required - (id)newsView:(UIView<NewsViewProtocol>*)newsView itemAtIndexPath:(NSIndexPath *)indexPath; - (NSInteger)numberOfItemsInNewsView:(UIView<NewsViewProtocol>*)newsView section:(NSInteger)section; - (BOOL)newsView:(UIView<NewsViewProtocol>*)newsView shouldDisplaySection:(NSInteger)section; @end @protocol NewsViewProtocol<NSObject> @required //Never retain delegate instance into implementation of this method - (void)setDelegate:(NSObject<NewsViewDelegate>*)delegate; //Never retain delegate instance into implementation of this method - (void)setDataSource:(NSObject<NewsViewDataSource>*)dataSource; - (void)reload; @end 

你可能会认为这是多余的。 在简单的视图控制器中,是的。 但是,如果你开发了非常复杂的屏幕和大量的数据,那么它给你一些优势:

  • 帮助你分离视图和控制器之间的责任。
  • 保持你的代码清晰。
  • 使您的代码更加可重用。

这就是响应者链的build立。 当你添加一个目标到你的button,只需提供nil目标:

 [mySpecialButton addTarget:nil action:@selector(mySpecialButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

nil目标基本上意味着“将mySpecialButtonTapped:发送到响应者链中可处理它的任何对象”。

现在你可以在响应者链中的任何地方处理这个select器,包括button本身,包含视图,包含视图控制器,UIApplication,最后是你的AppDelegate。 只需将此方法放在最适合您需求的对象中:

 - (void)mySpecialButtonTapped:(id)sender { NSLog("My special button was tapped!"); } 

如果您只想向上发送消息,则不需要委托或回叫块(如接受的答案中所示)。

xCode中的生活很简单。

从一开始就要确保你的xib View(里面有你的button的那个)与正确的ViewController类相关联。 这可以是新项目或自定义项目的默认ViewController类。

在此之后,这是魔术! 把你的视野分成2个小组。 目标是看你的xib和你的viewController代码(.m文件)。 现在按键盘上的控制键,拖动你的UIButton到代码。 selectIBAction。 它会产生一些你可以称之为其他语言的“监听者”的东西。 转到您的视图控制器的核心代码,并完成该方法!

那样容易! 玩的开心 :)

你并不需要这样的代表 – 这是如何使用UIButtons。 只需按住control并单击并从您的button拖到您的UIViewController的.m文件。 这将创build一个新的方法。 从那里,你可以打电话给你写的方法,或者只是复制粘贴到新的方法。

你可以试试这个:

 [yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside]; 

并在您的select器中指定的行动

 - (IBAction)yourButtonAction:(id)sender { //Action to perform } 

以编程方式在myViewController.m中添加button

 UIView *yourView = [[UIView alloc] init]; UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,100,21)]; [yourButton addTarget:self action:@selector(yourMethod) forControlEvents:UIControlEventTouchDown]; [yourView addSubview:yourButton]; 

更多信息在这里 。