animando transiciones UIView como expandir punto a círculo

En mi aplicación para iPhone, necesito implementar un tipo diferente de transición.

eso fue

próxima vista abierta desde la vista actual,

se muestra como un punto y el punto se expande lentamente como un círculo con el círculo. La vista siguiente se muestra parcialmente con la parte del círculo, finalmente el círculo se expande por completo y la siguiente vista aparece por completo.

Busco muchas transiciones como CATransitions, y algunas animaciones sobre el controller de cocoa, pero no encontré este tipo de transición, ¿puede alguien ayudarme por favor?

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

en mi caso lo hice de esa manera:

establezca una instancia de CAShapeLayer como la propiedad de la máscara de la capa de su subclass de vista personalizada

 @interface MyCustomView () @property (nonatomic, strong) CircleShapeLayer *circleShapeLayer; @end @implementation MyCustomView - (id) initWithFrame: (CGRect) frame { self = [super initWithFrame: CGRectZero]; if (self) { self.layer.mask = self.shapeLayer; [self.layer.mask setValue: @(0) forKeyPath: @"transform.scale"]; } return self; } 

Amplíe esta capa de máscara a tamaño completo. código de su vista:

 - (void) zoom { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; animation.fromValue = [self.layer.mask valueForKeyPath: @"transform.scale"]; animation.toValue = @(1); animation.duration = 2.0; animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; animation.delegate = self; // Important: change the actual layer property before installing the animation. [self.layer.mask setValue: animation.toValue forKeyPath: animation.keyPath]; // Now install the explicit animation, overriding the implicit animation. [self.layer.mask addAnimation: animation forKey: animation.keyPath]; return; } - (CAShapeLayer *) circleShapeLayer { if (!_ circleShapeLayer) { _circleShapeLayer = [SGMaskLayer layer]; _circleShapeLayer.delegate = _shapeLayer; _circleShapeLayer.frame = self.bounds; _circleShapeLayer.needsDisplayOnBoundsChange = YES; } return _circleShapeLayer; } @end 

el código de la capa de máscara:

 @interface CircleShapeLayer : CAShapeLayer @end @implementation CircleShapeLayer - (void) drawLayer: (CALayer *) layer inContext: (CGContextRef) ctx { UIGraphicsPushContext(ctx); UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect: self.bounds]; self.path = circlePath.CGPath; UIGraphicsPopContext(); } @end 

de la documentation:

El canal alfa de la capa determina cuánto muestra el contenido y el background de la capa. Los píxeles completamente o parcialmente opacos permiten que el contenido subyacente se muestre, pero los píxeles totalmente transparentes bloquean ese contenido.

El valor pnetworkingeterminado de esta propiedad es nil nil. Al configurar una máscara, recuerde establecer el tamaño y la position de la capa de máscara para asegurarse de que esté alineada correctamente con la capa que enmascara.

así que dibujé un círculo con UIBezierPath para lograr la máscara networkingonda. al principio puse el factor de escala de la máscara en 0, así que nada de la capa de la vista es visible. entonces el factor de escala se establece en 1 (llenando los límites de la capa) animados, lo que da una agradable animation de un círculo que aumenta su radio desde el centro.

es posible que necesite una animation más que cambie el punto central de su vista. Ambas animaciones pueden envolverse en un CAAnimationGroup.

Bueno, creo que puedo ofrecerle una solución. En lugar de empujar a la siguiente vista como un punto. Sugiero que agregue una simple animation de puntos en la ViewWillAppear de vista de ViewWillAppear en la que debe empujarse. Ahora el método push seguiría siendo el mismo

 [self.navigationController pushViewController:NewView animated:YES]; 

Pero en el ViewWillAppear el código sería tal que el punto se expandiría a un círculo y revelaría la Nueva Vista debajo de él. Espero que entiendas la lógica que estoy tratando de explicar aquí. Cualquier problema házmelo saber.

Abrir en primera vista:

// El método de delegado para la anotación seleccionó – (void) tapOnAnnotation: (RMAnnotation *) anotación onMap: (RMMapView *) map; {// Para get el punto de contacto del marcador GMS para establecerlos como transito circular pos CGPoint markerPoint = annotation.position; x = markerPoint.x; y = markerPoint.y;

  circleSize = 10; radiusChange = 0; //Populate Same Values to next view to close VenueScreen.x = x; VenueScreen.y = y; VenueScreen.view.hidden = YES; timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(openVenueScreen) userInfo:nil repeats:YES]; VenueScreen.view.frame = CGRectMake(0, 0, 320, 480); [self.view addSubview:VenueScreen.view]; } //Circular transition to open Next view -(void)openVenueScreen { VenueScreen.view.hidden = NO; VenueScreen.view.userInteractionEnabled = NO; VenueScreen.view.alpha = 0.9; self.view.userInteractionEnabled = NO; int rChange = 0; // Its doing proper masking while changing this value int radius = circleSize-rChange; CAShapeLayer *circleShapeLayer = [CAShapeLayer layer]; // Make a circular shape circleShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(x+radiusChange, y+radiusChange, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath; radiusChange = radiusChange-10; // Configure the apperence of the circle [[VenueScreen.view layer] setMask:circleShapeLayer]; //Start Transition circleSize = circleSize+10; if (circleSize > 480) { [[VenueScreen.view layer] setMask:nil]; [timer invalidate]; //Stop titmer VenueScreen.view.userInteractionEnabled = YES; self.view.userInteractionEnabled = YES; VenueScreen.view.alpha = 1; //Populate to next view to close VenueScreen.radiusChange = radiusChange; } } 

Cerrar en la vista siguiente:

 //Close button Action -(IBAction)DismissVenueScreen:(id)sender; { timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(dismissVenueScreen) userInfo:nil repeats:YES]; NSLog(@"close button clciked"); } //Circular trasition to Close window -(void)dismissVenueScreen { int rChange = 0; // Its doing proper masking while changing this value int radius = circleSize-rChange; CAShapeLayer *circleShapeLayer = [CAShapeLayer layer]; // Make a circular shape circleShapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(x+radiusChange,y+radiusChange, 2.0*radius, 2.0*radius) cornerRadius:radius].CGPath; // Configure the apperence of the circle [[self.view layer] setMask:circleShapeLayer]; self.view.layer.masksToBounds = YES; radiusChange = radiusChange+10; circleSize = circleSize-10; if (circleSize <= 0) { [timer invalidate]; //Stop titmer [[self.view layer] setMask:nil]; [self.view removeFromSuperview]; circleSize = 480; } }