縦長のビューを作って、縦にドラッグした時と横にドラッグした時で挙動を変えたい。
例えば、こんなUIScrollViewがあったとする。
frame => CGRectMake(0,20,320,460)
contentSize => CGSizeMake(320, 800)
これなら通常なら横にドラッグしても何も起こらない。
縦のスクロールは生かしたまま、横にドラッグした時に何かさせたい。
実装方法
touchesBeganでタップ開始位置を取得。
1回目のtouchesMovedで移動先位置を取得。
移動距離を取って、YとXどっちの方が変化が大きいかで挙動を振り分ける。
Xの変化の方が大きい場合は、scrollEnabledをFLASEにする。
だがしかし、touchesBeganしたあとにscrollEnabledを変えてももう遅い。
scrollEnabledの設定をしてからtouchesBeganが呼ばれないといけなかった。
で、解決策として、touchesMovedの中で、以下3つを実行する。
これでタップしたあとでもscrollEnabledの設定を変更出来た。
・self setScrollEnabled
・super touchesBegan
・super touchesEnded
使い方は、UIScrollSwitchViewを継承して、以下メソッドをオーバーライド。
- (void)touchesSwitchBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesSwitchMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesSwitchEnded:(NSSet *)touches withEvent:(UIEvent *)event;
ソース
UIScrollSwitchView.h
#import <UIKit/UIKit.h> enum { TAP_BEGAN, TAP_MOVED, TAP_ENDED }; @interface UIScrollSwitchView : UIScrollView { NSInteger tapStatus; CGPoint tapStart; } - (void)touchesSwitchBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesSwitchMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesSwitchEnded:(NSSet *)touches withEvent:(UIEvent *)event; @property (nonatomic) NSInteger tapStatus; @property (nonatomic) CGPoint tapStart; @end
UIScrollSwitchView.m
#import "UIScrollSwitchView.h" @implementation UIScrollSwitchView @synthesize tapStatus; @synthesize tapStart; - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { // Initialization code self.scrollEnabled = YES; self.delaysContentTouches = YES; self.tapStatus = TAP_ENDED; } return self; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ /* Touches */ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //NSLog(@"UIScrollSwitchView touchesBegan"); tapStatus = TAP_BEGAN; UITouch *touch = [[touches allObjects] objectAtIndex:0]; CGPoint location = [touch locationInView:self]; [self setTapStart:location]; [self touchesSwitchBegan:touches withEvent:event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { //NSLog(@"UIScrollSwitchView touchesMoved"); if (tapStatus==TAP_BEGAN) { tapStatus = TAP_MOVED; UITouch *touch = [[touches allObjects] objectAtIndex:0]; CGPoint location = [touch locationInView:self]; NSInteger move_x = abs(location.x - tapStart.x); NSInteger move_y = abs(location.y - tapStart.y); // 横に動いた if (move_y<move_x) { [self setScrollEnabled:FALSE]; [super touchesBegan:touches withEvent:event]; [super touchesEnded:touches withEvent:event]; } } if (self.scrollEnabled==FALSE) { [self touchesSwitchMoved:touches withEvent:event]; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //NSLog(@"UIScrollSwitchView touchesEnded"); tapStatus = TAP_ENDED; [self setScrollEnabled:TRUE]; [self touchesSwitchEnded:touches withEvent:event]; } /* Touch Switch */ - (void)touchesSwitchBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"UIScrollSwitchView touchesSwitchBegan"); } - (void)touchesSwitchMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"UIScrollSwitchView touchesSwitchMoved"); } - (void)touchesSwitchEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"UIScrollSwitchView touchesSwitchEnded"); } - (void)dealloc { [super dealloc]; } @end