从View中触发UIViewController中的方法

时间:2013-03-12 12:36:16

标签: ios cocoa-touch uiviewcontroller

我有一个UIViewController,其UIView包含UIButton。我想在按钮点击事件中触发UIViewController中的方法 保持对UIViewController的引用似乎不是一个好主意,如下面的链接所示: Get to UIViewController from UIView?

所以我想使用委托来实现这个目标。有关如何实现这一目标的任何提示吗?

7 个答案:

答案 0 :(得分:9)

你可以做这样的事情

<强> 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];

 }

答案 1 :(得分:3)

这就是响应者链的构建方式。向目标添加目标时,只需为目标提供nil

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

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

现在,您可以在响应程序链中的任何位置处理此选择器,其中包括按钮本身,包含视图,包含视图控制器,UIApplication以及最终的AppDelegate。只需将此方法放在最适合您需求的对象中:

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

如果您只是想要发送消息,则不需要委托或回调块(如在接受的答案中)。

答案 2 :(得分:1)

我猜你期望更基本的东西然后只是将一些按钮动作传递给控制器​​。 在模型/视图/控制器协作的情况下,我总是遵循MVC模式。它解决了您的问题和许多其他问题。我想分享我的经验。

  1. 将控制器与视图和模型分开:不要将所有“业务逻辑”放入与视图相关的类中;这使得代码非常不可用。使控制器类承载此代码,但要确保控制器类不会对表示做出太多假设。
  2. 使用@protocol定义回调API,如果不是所有方法都需要使用@optional
  3. 对于视图定义协议,如<view class name>Protocol(示例NewsViewProtocol)。对于控制器定义委托,如<view class name>Delegate(示例NewsViewDelegate)和dataSource,如<view class name>DataSource(示例NewsViewDataSource)。将所有这些@protocols保存在一个名为<view class name>Protocol.h的单独文件中(示例NewsViewProtocol.h)
  4. 简短的例子:

    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
    

    您可能认为这是多余的。在简单视图控制器中,YES。但是如果您使用大量数据开发非常复杂的屏幕,那么它将为您带来以下优势:

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

答案 3 :(得分:0)

xCode的生活很简单。

一开始,请确保您的xib视图(其中包含按钮的视图)与右侧ViewController类相关联。这可以是新项目或自定义项目附带的默认ViewController类。

在此之后,这里出现了魔术!将您的视图分为2个面板。目标是查看您的xib和您的viewController代码(.m文件)。现在按键盘的控制键并将UIButton拖到代码中。选择IBAction。它会产生一些你可以用其他语言称为“听众”的东西。转到View Controller的核心代码并完成方法!

这很容易!玩得开心:))

答案 4 :(得分:-1)

你真的不需要代表 - 这是UIButtons的使用方式。只需按住Control键并单击并从按钮拖动到UIViewController的.m文件即可。这将创建一个新方法。从那里,您可以调用您编写的方法,也可以将您拥有的内容复制粘贴到新方法中。

答案 5 :(得分:-1)

以编程方式添加按钮,在myViewController.m

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];

更多信息here

答案 6 :(得分:-1)

你可以试试这个:

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

在你的选择器中指定动作

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