アニメーション中のレスポンスイベント

2256 ワード

ケース列


あるbuttonはアニメーションを通じて別の位置に移動し、移動中にボタンをクリックして何かをしたいと思っています.一般的には次の方法で処理します.
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //  
    button       = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    button.backgroundColor = [UIColor redColor];
    [button addTarget:self action:@selector(buttonEvent:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    //  
    [UIView animateWithDuration:10.f
                          delay:0
                        options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         button.frame = CGRectMake(0, 468, 100, 100);
                     } completion:^(BOOL finished) {
                         
    }];
}

- (void)buttonEvent:(UIButton *)button {
    NSLog(@"do something);
}

そして実際の過程で、実際の状況が次のように発見されました.
  • 移動中にボタンをクリックするのはログ出力のない
  • である.
  • ボタンアニメーションの終点をクリック(この時点でボタンのインタフェース上の位置が終点から遠いとしても)はログ出力されますが、これは私たちが望んでいる
  • ではありません.

    ぶんせき


    動画中に画面に移動が表示されるのはlayer中のpresentationLayerであり、layer中のmodelLayerは動画が開始された瞬間にframeCGRectMake(0, 468, 100, 100)になった言い換えれば、動画効果はpresentationLayerが位置を変えた結果であり、modelLayerは動画効果が得られなかった

    解決策

    touchesBeganメソッドで現在クリックしている点がpresentationLayerframeの中にあるかどうかを判断するには、その前に次の2つのことをすべきです.
  • 注記buttonaddTargetメソッド(そうでなければ上記の場合2)
  • .
  • 設定button.userInteractionEnabled = NO(そうでないと終点でbuttonのクリックでタッチイベントがブロックされる)
  • - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        CALayer *presentationLayer = button.layer.presentationLayer;
        CALayer *modelLayer = button.layer.modelLayer;
        NSLog(@"%@", NSStringFromCGRect(presentationLayer.frame));
        NSLog(@"%@", NSStringFromCGRect(modelLayer.frame));
        
        // presentationLayer 
        CGPoint point = [[touches anyObject] locationInView:self.view];
        if (CGRectContainsPoint(presentationLayer.frame, point)) {
            [self buttonEvent:nil];
        }
    }