を含むUIViewController
withがUIView
ありますUIButton
。UIViewController
ボタンクリックイベントでメソッドをトリガーしたい。
次のリンクにあるように、の参照を維持UIViewController
することは良い考えではないようです
。UIViewからUIViewControllerにアクセスしますか?
ですから、デリゲートを使用してこれを達成したいと思います。これを達成する方法についてのヒントはありますか?
を含むUIViewController
withがUIView
ありますUIButton
。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];
}
これがレスポンダーチェーンの目的です。ボタンにターゲットを追加するときは、ターゲットを指定するだけnil
です。
[mySpecialButton addTarget:nil
action:@selector(mySpecialButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
ターゲットとは、nil
基本的に「mySpecialButtonTapped:
レスポンダーチェーン内でそれを処理できるオブジェクトに送信する」ことを意味します。
これで、このセレクターをレスポンダーチェーンのどこでも処理できます。これには、ボタン自体、そのビューを含む、ビューコントローラーを含む、UIApplication、そして最後にAppDelegateが含まれます。このメソッドを、ニーズに最も適したオブジェクトに配置するだけです。
- (void)mySpecialButtonTapped:(id)sender {
NSLog("My special button was tapped!");
}
メッセージをバブルアップしたいだけの場合は、デリゲートやコールバックブロック(受け入れられた回答のように)は必要ありません。
コントローラーにボタンアクションを渡すだけで、もっと基本的なことを期待していたと思います。モデル/ビュー/コントローラーのコラボレーションの場合、私は常にMVCパターンに従います。それはあなたの問題と他の多くを解決します。そして、私の経験を共有したいと思います。
@protocol
、を使用してコールバックAPIを定義します。@optional
<view class name>Protocol
ビューの場合は、 (NewsViewProtocolの例)のようなプロトコルを定義します。コントローラの場合、デリゲートのように定義し<view class name>Delegate
(例NewsViewDelegate)、dataSourceのように定義します<view class name>DataSource
(例NewsViewDataSource)。<view class name>Protocol.h
このすべての@protocolsを(NewsViewProtocol.hの例)という名前の1つの別個のファイルに保持します。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
あなたはそれが冗長であると考えるかもしれません。シンプルビューコントローラーでは、はい。ただし、大量のデータを含む非常に複雑な画面を開発する場合は、次のようないくつかの利点があります。
xCodeでの生活は簡単です。
最初に、xibビュー(ボタンが内部にあるビュー)が正しいViewControllerクラスに関連付けられていることを確認してください。これは、新しいプロジェクトまたはカスタムプロジェクトに付属するデフォルトのViewControllerクラスにすることができます。
この後、魔法のトリックがやってくる!ビューを2つのパネルに分割します。目標は、xibとviewControllerコード(.mファイル)を確認することです。次に、キーボードのコントロールキーを押して、UIButtonをコードにドラッグします。IBActionを選択します。それはあなたが他の言語で「リスナー」と呼ぶことができる何かを生成します。View Controllerのコアコードに移動し、メソッドを完了します。
そんなに簡単!楽しむ :)
プログラムでボタンを追加するには、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];
詳細はこちら。
このためにデリゲートは実際には必要ありません。これは、UIButtonの使用方法です。Controlキーを押しながらクリックして、ボタンからUIViewControllerの.mファイルにドラッグします。これにより、新しいメソッドが作成されます。そこから、作成したメソッドを呼び出すか、新しいメソッドに持っているものをコピーして貼り付けることができます。
あなたはこれを試すことができます:
[yourButton addTarget:self action:@selector(yourButtonAction:) forControlEvents:UIControlEventTouchUpInside];
そしてセレクターでアクションを指定します
- (IBAction)yourButtonAction:(id)sender {
//Action to perform
}