Encierra la vista enmascarada que se anima demasiado rápido y no se puede tocar

Estoy intentando hacer una vista de image enmascarada en círculo con máscara animada y jugar con diferentes soluciones. El siguiente ejemplo hace el trabajo pero tengo dos problemas con él:

1) ¿Por qué es que no puedo hacer que la image sea táctil ? Agregando, por ejemplo un UITapGestureRecognizer no funciona. Mi conjetura es que la máscara impide que las acciones táctiles se propaguen al nivel inferior en la jerarquía de la vista.

2) La animation de la máscara se está ejecutando muy rápido y no puedo ajustar la duración usando la animation de bloque UIView

¿Cómo puedo resolver esto?

 - (void) addCircle { // this is the encapsulating view // base = [[UIView alloc] init]; // // this is the button background // base_bgr = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"c1_bgr.png"]]; base_bgr.center = CGPointMake(60, 140); [base addSubview:base_bgr]; // // icon image // base_icon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"c1_ico.png"]]; base_icon.center = CGPointMake(186*0.3/2, 182*0.3/2); base_icon.transform = CGAffineTransformMakeScale(0.3, 0.3); [base addSubview:base_icon]; // // the drawn circle mask layer // circleLayer = [CAShapeLayer layer]; // Give the layer the same bounds as your image view [circleLayer setBounds:CGRectMake(0.0f, 0.0f, [base_icon frame].size.width, [base_icon frame].size.height)]; // Position the circle [circleLayer setPosition:CGPointMake(186*0.3/2-7, 182*0.3/2-10)]; // Create a circle path. UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect: CGRectMake(0.0f, 0.0f, 70.0f, 70.0f)]; // Set the path on the layer [circleLayer setPath:[path CGPath]]; [[base layer] setMask:circleLayer]; [self.view addSubview:base]; base.center = CGPointMake(100, 100); base.userInteractionEnabled = YES; base_bgr.userInteractionEnabled = YES; base_icon.userInteractionEnabled = YES; // // NOT working: UITapGestureRecognizer // UITapGestureRecognizer *tapgesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapit:)]; [base_icon addGestureRecognizer:tapgesture]; // // BAD but WORKS :) properly positioned UIButton over the masked image // base_btn = [UIButton buttonWithType:UIButtonTypeCustom]; base_btn.frame = CGRectMake(base.frame.origin.x, base.frame.origin.y, base_icon.frame.size.width, base_icon.frame.size.height); [base_btn addTarget:self action:@selector(tapit:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:base_btn]; } 

Este es el manejador de taps y esta es la animation de la máscara. Cualquier número que probé en duración, está animando rápido, aproximadamente 0.25 segundos, y no puedo ajustarlo.

 - (void) tapit:(id) sender { //... [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^ { [circleLayer setTransform:CATransform3DMakeScale(10.0, 10.0, 1.0)]; } completion:^(BOOL finished) { // it is not necessary if I manage to make the icon image tappable base_btn.frame = [base convertRect:base_icon.frame toView:self.view]; }]; } } 

1) los toques no se propagan hacia abajo desde la base porque se inicia sin un marco, por lo que su marco será CGRectZero. Las vistas no reciben events táctiles que comiencen fuera de sus límites. Simplemente establezca un marco válido en la base que incluya el objective de toque completo.

2) setTransform: en una capa invoca una animation implícita que utiliza la duración pnetworkingeterminada de Core Animation de 0.25 (lo has adivinado :). La mejor solución sería utilizar CABasicAnimation lugar de la animation basada en UIView . Algo como esto:

 CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnimation.toValue = @(10.0f); scaleAnimation.duration = 2; [circleLayer addAnimation:scaleAnimation forKey:nil]; 

Nota: de forma pnetworkingeterminada, CABasicAnimation se eliminará de una capa cuando se complete y la capa recuperará valores antiguos. Puede evitarlo, por ejemplo, configurando la propiedad removedOnCompletion la animation en NO y eliminándola usted mismo más tarde utilizando el CALayer removeAnimationForKey: simplemente de removeAnimationForKey: (simplemente establezca una key en lugar de pasar nada si agrega la animation), pero eso depende de qué quiere exactamente lograr con esto

    Intereting Posts