How to Custom Modal View Controller Presenting Animation

How to custom Modal View Controller presenting animation?

You just need to add the transition to the window's layer, and present your controller rather than pushing it:

     CATransition* transition = [CATransition animation];
transition.duration = 1;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromBottom;
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:adjustViewController animated:NO completion:nil];

How to present a modal view controller like with UIKit's UIViewControllerTransitioningDelegate?

Well there is no built-in such flexibility say with standard .sheet, but it can be implemented custom very fast.

Here is simple demo (Xcode 13.3 / iOS 15.4)

demo

Main part:

struct ElementsList: View {
// ...
ModalView(isPresented: $isModal) {
List(elements, id: \.self) {

struct ModalView<V: View>: View {
@Binding var isPresented: Bool
// ...
ZStack {
content()
ZStack {
VStack {
if isPresented {
Color.black.opacity(0.8)
.transition(.opacity)
}
}.animation(.easeInOut(duration: 0.25), value: isPresented)

Complete test code in project is here

Implement custom animation to present modal view from specified view on iPad

What I did was creating a new category for UIViewController as follows

UIViewController+ShowModalFromView.h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface UIViewController (ShowModalFromView)

- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view;

@end

UIViewController+ShowModalFromView.m

#import "UIViewController+ShowModalFromView.h"

@implementation UIViewController (ShowModalFromView)

- (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view
{
modalViewController.modalPresentationStyle = UIModalPresentationFormSheet;

// Add the modal viewController but don't animate it. We will handle the animation manually
[self presentModalViewController:modalViewController animated:NO];

// Remove the shadow. It causes weird artifacts while animating the view.
CGColorRef originalShadowColor = modalViewController.view.superview.layer.shadowColor;
modalViewController.view.superview.layer.shadowColor = [[UIColor clearColor] CGColor];

// Save the original size of the viewController's view
CGRect originalFrame = modalViewController.view.superview.frame;

// Set the frame to the one of the view we want to animate from
modalViewController.view.superview.frame = view.frame;

// Begin animation
[UIView animateWithDuration:1.0f
animations:^{
// Set the original frame back
modalViewController.view.superview.frame = originalFrame;
}
completion:^(BOOL finished) {
// Set the original shadow color back after the animation has finished
modalViewController.view.superview.layer.shadowColor = originalShadowColor;
}];
}

@end

It's pretty straight forward. Please let me know if this helps you.

UPDATE

I've updated the answer to use animation blocks instead of [UIView beginAnimations:nil context:nil]; / [UIView commitAnimations] pair.

Present a modal view using fade-in animation

Just set the modalTransitionStyle property for the viewController. (Documentation)

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:@"login"];
[ivc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:ivc animated:YES completion:nil];

In Swift:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "login")
viewController.modalTransitionStyle = .crossDissolve
present(viewController, animated: true, completion: nil)


Related Topics



Leave a reply



Submit