2つの観測:
私は、一般的にこのようなもののためのジェスチャー認識装置、ではない様々なtouchUp...
メソッドを使用します。
あなたはサブビューを通して高速列挙を望んでいないと言いましたが、どうしてですか?他のクラスとは異なるクラスがあるからといって、問題はありません(isKindOfClass
メソッドをテストするだけなので)。なぜなら、彼らが並んでいないからといって、本当に違いはないからです。
とにかく、このようなもののために、私は頻繁に共有親ビュー(例えば、通常View Controllerのビュー)にジェスチャー認識を置く、その後、現在するCGPointが含まれている見ることがサブビューを列挙します?
CGPoint location = [sender locationInView:self.view];
for (UIView *subview in self.view.subviews)
{
if (CGRectContainsPoint(subview.frame, location))
{
// do your appropriate highlighting
if ([subview isKindOfClass:[UIButton class]])
{
// something for buttons
}
else if ([subview isKindOfClass:[UIImageView class]])
{
// something for imageviews
}
return;
}
}
これがあなたにとって意味をなさすかどうかわかりませんが、私にとっては最も簡単です。あなたの意図を明確にすれば、おそらく私は自分の答えをさらに洗練することができます。
実際の例のように、クリックされた最初と最後のサブビューを追跡する連続ジェスチャ認識プログラムを定義することができます(サブビューでジェスチャーを開始しないと、ジェスチャーは生成されません。
SubviewGestureRecognizer *recognizer = [[SubviewGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouches:)];
[self.view addGestureRecognizer:recognizer];
をそして、としてあなたのハンドラを定義します。
@interface SubviewGestureRecognizer : UIGestureRecognizer
@property (nonatomic,strong) UIView *firstSubview;
@property (nonatomic,strong) UIView *currentSubview;
@end
@implementation SubviewGestureRecognizer
- (id) initWithTarget:(id)target action:(SEL)action
{
self = [super initWithTarget:target action:action];
if (self)
{
self.firstSubview = nil;
self.currentSubview = nil;
}
return self;
}
// you might want to tweak this `identifySubview` to only look
// for buttons and imageviews, or items with nonzero tag properties,
// or recursively navigate if it encounters container UIViews
// or whatever suits your app
- (UIView *)identifySubview:(NSSet *)touches
{
CGPoint location = [[touches anyObject] locationInView:self.view];
for (UIView *subview in self.view.subviews)
{
if (CGRectContainsPoint(subview.frame, location))
{
return subview;
}
}
return nil;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
if ([touches count] != 1)
{
self.state = UIGestureRecognizerStateFailed;
return;
}
self.firstSubview = [self identifySubview:touches];
self.currentSubview = self.firstSubview;
if (self.firstSubview == nil)
self.state = UIGestureRecognizerStateFailed;
else
self.state = UIGestureRecognizerStateBegan;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
if (self.state == UIGestureRecognizerStateFailed) return;
self.currentSubview = [self identifySubview:touches];
self.state = UIGestureRecognizerStateChanged;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
self.currentSubview = [self identifySubview:touches];
if (self.currentSubview != nil)
self.state = UIGestureRecognizerStateEnded;
else
self.state = UIGestureRecognizerStateFailed;
}
- (void)reset
{
[super reset];
self.firstSubview = nil;
self.currentSubview = nil;
}
あなたはその後、viewDidLoad
でこれを設定することができます:あなたがサブビューにあなたのジェスチャーを停止しない場合、それは例えば、)全部をキャンセルそのような(これは、ボタンと画像ビューで動作し、両方ともサポートsetHighlighted
)の利点:
- (void)handleTouches:(SubviewGestureRecognizer *)sender
{
static UIControl *previousControl = nil;
if (sender.state == UIGestureRecognizerStateBegan || sender.state == UIGestureRecognizerStateChanged)
{
if (sender.state == UIGestureRecognizerStateBegan)
previousControl = nil;
UIView *subview = sender.currentSubview;
if (previousControl != subview)
{
// reset the old one (if any)
[previousControl setHighlighted:NO];
// highlight the new one
previousControl = (UIControl *)subview;
[previousControl setHighlighted:YES];
}
}
else if (sender.state == UIGestureRecognizerStateEnded)
{
if (previousControl)
{
[previousControl setHighlighted:NO];
NSLog(@"successfully touchdown on %@ and touchup on %@", sender.firstSubview, sender.currentSubview);
}
}
else if (sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed)
{
[previousControl setHighlighted:NO];
NSLog(@"cancelled/failed gesture");
}
}
出典
2012-08-12 03:25:27
Rob
あなたはいくつかの低レベルの動作(あなたが指を押して別のボタンにドラッグすると解決しますが、あなたが解決しようとしているより広い問題は説明していないので、あなたの質問に少し答えるタフ。あなたは何をしようとしているのですか?ワンタッチでタッチを検出し、別のボタンでタッチアップするだけですか? Swypeのようなタイピングスキームのシリーズ全体ですか?提案された回答は、あなたがしようとしていることに依存するかもしれません。 – Rob
私はまた、フレームワークの高速列挙ではないことについて最後の点を理解していません。なぜなら、異なるサブビュータイプについて心配している場合、正しい動作が何であったかを知るために 'isKindOfClass'をチェックするだけだからです。私の答えを見てください。 – Rob
UIImageの代わりにUIImageViewを使用すると仮定します – WolfLink