以下の記事でViewControllerからViewを切り離すことについて書きましたが、具体的にViewとViewControllerを繋ぐ方法についての補足です。
IB/Storyboard使わない派のlayoutSubviewsによるレイアウト調整
Viewのパブリックプロパティを使う方法
まずは切り離したViewのうち、ViewControllerでアクセスするサブビューをパブリックプロパティにする方法です。
移行コストが少ないので面倒臭い時はまずこの方法を使い、余裕がある時に後のことを考えて後述のデリゲートを使う方法に書き変えるといいかもしれません。
###ポイント
- 画面パーツはViewに配置する
- ViewControllerからアクセスする必要があるパーツはパブリックプロパティにする
- ViewControllerでViewを生成した後、パブリックプロパティ経由でイベントハンドラ登録等を行う
View.h
@interface HogeView : UIView
// パブリックプロパティ
@property(nonatomic, strong) UIButton okButton;
@property(nonatomic, strong) UIButton cancelButton;
@end
ViewController.m
@interface HogeViewController ()
@property(nonatomic, strong) HogeView *hogeView;
@end
@implementation HogeViewController
-(void) loadView {
// View生成
self.hogeView = [[HogeView alloc] init];
self.view = self.hogeView;
// 繋ぎ部分
// ViewControllerからイベントハンドラ登録
[self.hogeView.okButton addTarget:self action:@selector(onOkTapped) forControlEvents: UIControlEventTouchUpInside];
[self.hogeView.cancelButton addTarget:self action:@selector(onCancelTapped) forControlEvents: UIControlEventTouchUpInside];
}
// イベントハンドラ
-(void) onOkTapped {
...
}
-(void) onCancelTapped {
...
}
@end
デリゲートを定義する方法
より変更に強い設計にするにはView専用のデリゲートを定義し、ViewとViewControllerをデリゲート経由で繋ぐ方法です。
###ポイント
- View専用のデリゲートViewDelegateを定義する
- ViewではViewDelegateのみパブリックプロパティにする
- ViewDelegateのセッタ内でイベントハンドラ登録等を行う
- ViewControllerはViewDelegateを実装する
- ViewControllerでViewを生成した後、ViewのViewDelegateを設定する
View.h
// 専用デリゲート
@protocol HogeViewDelegate
-(void) onOkTapped;
-(void) onCancelTapped;
@end
@interface HogeView : UIView
// デリゲートのみパブリックにする
@property(nonatomic, weak) id<HogeViewDelegate> delegate;
@end
View.m
@interface HogeView
// サブビューはプライベートにする
@property(nonatomic, strong) UIButton okButton;
@property(nonatomic, strong) UIButton cancelButton;
@end
@implementation HogeView
// デリゲートのセッタ
-(void) setDelegate:(id<HogeViewDelegate>)delegate {
_delegate = delegate;
// デリゲート経由でイベントハンドラ登録
[self.okButton addTarget:delegate action:@selector(onOkTapped) forControlEvents: UIControlEventTouchUpInside];
[self.cancelButton addTarget:delegate action:@selector(onCancelTapped) forControlEvents: UIControlEventTouchUpInside]
}
@end
ViewController.m
// デリゲートを実装
@interface HogeViewController () <HogeViewDelegate>
@property(nonatomic, strong) HogeView *hogeView;
@end
@implementation HogeViewController
-(void) loadView {
// View生成
self.hogeView = [[HogeView alloc] init];
self.view = self.hogeView;
// 繋ぎ部分
self.hogeView.delegate = self;
}
// イベントハンドラ
-(void) onOkTapped {
...
}
-(void) onCancelTapped {
...
}
@end