uitoolbarの同時タッチを防ぐ
TRANSCRIPT
potatotips UIToolbarの同時タッチを防ぐ
デンソーアイティーラボラトリ @sonson_twit 吉田悠一
本業
自己紹介
sonsongithubで検索
2tchのモジュールをOSSに
• UZMultipleLayeredPopoverController
• UZTextView
• UZInputCandidateAccessory
コードの保守性を高めるために
• モジュールを切り出して公開する
まずはこの症状をご覧ください
問題点
• 同時入力できてしまう
• ツールバーのボタン
• UINav.Con.のジェスチャ
!
• UIViewControllerの階層構造が壊れる
• MobileSafariはロックして回避しているようだ
対策案
• UIBarButtonItemに対策を施す
• exclusiveTouch?
• UIBarButtonItemからdownとupを奪う
exclusiveTouch
• 役立たず
• だが,ツールバー上のボタン二つ同時押しは避けることができた
/**! * UIToolbarでボタンふたつの同時押しを防止する.! **/!- (void)setExclusiveForUIBarButtonsOnToolbar {!! for (UIView* view in [self.navigationController.toolbar subviews]) {!! ! view.exclusiveTouch=YES;!! }!}
これもグレーといえば,グレー
UIBarButtonItemのイベント
• タップイベントの横取りが直接できない
• C2ToolbarButton - undocumented class
• viewからswizzlingでタップイベントを奪う
• customにしてUIButtonを内蔵する
• UIToolbarにジェスチャをつける
Undocumented API
• ダメですわ・・・・
Swizzling
• え・・・そんなんやりたくないです
• 昔,リジェクトされたし・・・・
UIButton in UIBarButtonItem
• え・・・汎用性なくなりますよ
• Storyboardのボタンを全部作り替えるとか
• 難のためにそんなアホなことを
• 嫌です
/**! * UIButtonをUIBarButtonItemにセット! * addTergetで触ったタイミングを検出・・・! **/!UIButton *insideButton = [UIButton buttonWithType:UIButtonTypeCustom];!insideButton.bounds = CGRectMake(0, 0, 44, 44);![insideButton setImage:[UIImage imageNamed:@"hoge.png"] forState:UIControlStateNormal];!UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:insideButton];
ないわー,絶対ないわー!Storyboardとか使えないですやん
UIToolbarにジェスチャ
• UIGestureRecognizerのサブクラスを実装
• touchesBegin
• touchesCancelled, touchesEnded
• ジェスチャは失敗させる
• UINavigationControllerにコールバック
• interactiveGestureRecognizer.enable
- (void)viewDidLoad {! [super viewDidLoad];!! C2ToolbarTapGestureRecognizer* tapGesture = !! ! [[C2ToolbarTapGestureRecognizer alloc] initWithTarget:nil action:nil];!! tapGesture.dummyDelegate = self;!! tapGesture.delegate = self;!! [self.toolbar addGestureRecognizer:tapGesture];!}
カスタムのGestureRecognizerをUIToolbarにセット.
UINavigationControllerのサブクラスで
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {!! self.state = UIGestureRecognizerStatePossible;!! [self.dummyDelegate didBeginDummyTap:self];!}!!- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {!! self.state = UIGestureRecognizerStateFailed;!! [self.dummyDelegate didEndDummyTap:self];!}!!- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {!! self.state = UIGestureRecognizerStateFailed;!! [self.dummyDelegate didEndDummyTap:self];!}
タップのダウン・アップを検出し,UINav.に送る
この辺が妥協点か・・・・!コードも使い回せるし,汎用的だし,書き直しがないし!
!他にいい方法があったら教えてください.
まとめ
• 自己紹介
• 2tchのモジュール
• ツールバーとジェスチャの衝突を防ぎたい
backup slide
backup