ios - bar - cambiar color de fondo ionic
Circunde la vista enmascarada que anima demasiado rĂ¡pido y no se puede tocar (1)
Intento hacer una vista de imagen enmascarada con máscara animada y jugar con diferentes soluciones. El siguiente ejemplo hace el trabajo, pero tengo dos problemas con él:
1) ¿Por qué no puedo hacer que la imagen se pueda tocar ? Agregar por ej. un UITapGestureRecognizer
no funciona. Mi suposición es que la máscara evita que las acciones táctiles se propaguen al nivel inferior en la jerarquía de vistas.
2) Animar la máscara se ejecuta muy rápido y no puedo ajustar la duración usando animación 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 tap, y aquí está la animación de máscara. Cualquiera sea el número que intenté en duración, se está animando rápidamente, 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 desde la base
porque se inició sin un marco, por lo que su marco será CGRectZero. Las vistas no reciben eventos táctiles que comienzan fuera de sus límites. Simplemente establece un marco válido en la base
que incluye todo el objetivo tap.
2) setTransform:
en una capa invoca una animación implícita que usa la duración predeterminada de Core Animation de 0.25 (lo has adivinado :)). La mejor solución sería usar CABasicAnimation
lugar de la animación 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 predeterminada, CABasicAnimation
se eliminará de una capa cuando se complete y la capa volverá a los valores anteriores. Puede evitarlo, por ejemplo, estableciendo la propiedad removedOnCompletion
esa animación en NO
y eliminándola usted mismo más tarde utilizando el CALayer
de removeAnimationForKey:
(simplemente establezca una clave en lugar de pasar nada al agregar la animación), pero eso depende de qué es exactamente lo que quiere lograr con esto.