SlideShare a Scribd company logo
Custom UIViewController
Transitions
Ján Ilavský - @split82
iPhone OS 3.0
iOS 7
Modal View Controller
- (void)presentViewController:animated:completion:
!
- (void)dismissViewControllerAnimated:completion:
UIModalTransitionStyle modalTransitionStyle
typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
UIModalTransitionStylePartialCurl,
#endif
};
UIModalPresentationStyle modalPresentationStyle
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
UIModalPresentationPageSheet,
UIModalPresentationFormSheet,
UIModalPresentationCurrentContext,
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
UIModalPresentationCustom,
UIModalPresentationNone = -1,
#endif
};
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
UIModalPresentationFullScreen = 0,
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_3_2
UIModalPresentationPageSheet,
UIModalPresentationFormSheet,
UIModalPresentationCurrentContext,
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
UIModalPresentationCustom,
UIModalPresentationNone = -1,
#endif
};
Custom Fullscreen
Non-interactive Transitions
Demo
TestViewController *viewController = [TestViewController new];
!
viewController.transitioningDelegate = ???
!
[self presentViewController:viewController animated:YES
completion:nil];
TestViewController *viewController = [TestViewController new];
!
viewController.transitioningDelegate = ???
!
[self presentViewController:viewController animated:YES
completion:nil];
@protocol UIViewControllerTransitioningDelegate <NSObject>
!
@optional
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting sourceController:
(UIViewController *)source;
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController *)dismissed;
!
!
- (id
<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id
<UIViewControllerAnimatedTransitioning>)animator;
!
!
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id <UIViewControllerAnimatedTransitioning>)animator;
!
!
@end
@protocol UIViewControllerTransitioningDelegate <NSObject>
!
@optional
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting sourceController:
(UIViewController *)source;
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController *)dismissed;
!
!
- (id
<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id
<UIViewControllerAnimatedTransitioning>)animator;
!
!
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id <UIViewControllerAnimatedTransitioning>)animator;
!
!
@end
@protocol UIViewControllerTransitioningDelegate <NSObject>
!
@optional
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting sourceController:
(UIViewController *)source;
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController *)dismissed;
!
!
- (id
<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id
<UIViewControllerAnimatedTransitioning>)animator;
!
!
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id <UIViewControllerAnimatedTransitioning>)animator;
!
!
@end
UIViewController UIViewController
id <UIViewControllerTransitioningDelegate>
transitioningDelegate
animationControllerForPresentedController… animationControllerForDismissedController
id <UIViewControllerAnimatedTransitioning>
id <UIViewControllerAnimatedTransitioning>
present
dismiss
@protocol UIViewControllerAnimatedTransitioning <NSObject>
!
!
- (NSTimeInterval)transitionDuration:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
- (void)animateTransition:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
!
@optional
!
- (void)animationEnded:(BOOL)transitionCompleted;
!
@end
@protocol UIViewControllerAnimatedTransitioning <NSObject>
!
!
- (NSTimeInterval)transitionDuration:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
- (void)animateTransition:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
!
@optional
!
- (void)animationEnded:(BOOL)transitionCompleted;
!
@end
UIView UIView
UIViewController UIViewController
@protocol UIViewControllerAnimatedTransitioning <NSObject>
!
!
- (NSTimeInterval)transitionDuration:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
- (void)animateTransition:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
!
@optional
!
- (void)animationEnded:(BOOL)transitionCompleted;
!
@end
@protocol UIViewControllerAnimatedTransitioning <NSObject>
!
!
- (NSTimeInterval)transitionDuration:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
- (void)animateTransition:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
!
@optional
!
- (void)animationEnded:(BOOL)transitionCompleted;
!
@end
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
!
Container View
UIView UIView
UIViewController UIViewController
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
initialFrameForViewController finalFrameForViewController
from CGRectZero
to CGRectZero
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
UIViewController *fromViewController = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
!
UIViewController *toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
!
!
toViewController.view.alpha = 0.0f;
toViewController.view.frame = [transitionContext
finalFrameForViewController:toViewController];
!
[transitionContext.containerView addSubview:toViewController.view];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
//[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
Custom Non-Fullscreen
Non-interactive Transitions
TestViewController *viewController = [TestViewController new];
!
viewController.modalPresentationStyle = UIModalPresentationCustom;
viewController.transitioningDelegate = ???
!
[self presentViewController:viewController animated:YES
completion:nil];
UIView
UIView
Demo
Presentation != Dismissal
Presentation
!
Container View
UIView UIView
UIViewController UIViewController
Dismission
!
Container View
UIView UIView
UIViewController UIViewController
initialFrameForViewController finalFrameForViewController
from
to CGRectZero CGRectZero
Presentation
initialFrameForViewController finalFrameForViewController
from CGRectZero
to CGRectZero
Dismissal
viewWillDissapear
!
viewDidDissapear
FromViewController
Presentation
viewWillAppear
!
viewDidAppear
ToViewController
Dismissal
[transitionContext.containerView
addSubview:toViewController.view];
!
toViewController.view.frame = CGRectInset([transitionContext
initialFrameForViewController:fromViewController], 32.0f, 32.0f);
!
toViewController.view.alpha = 0.0f;
!
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
Presentation
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
fromViewController.view.alpha = 0.0f;
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
Dismissal
Interactive Transitions
start complete
start complete
cancel
finish
updating
Demo
UIViewController UIViewController
id <UIViewControllerTransitioningDelegate>
transitioningDelegate
animationControllerForPresentedController… animationControllerForDismissedController
id <UIViewControllerAnimatedTransitioning>
id <UIViewControllerAnimatedTransitioning>
present
dismiss
@protocol UIViewControllerTransitioningDelegate <NSObject>
!
@optional
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting sourceController:
(UIViewController *)source;
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController *)dismissed;
!
!
- (id
<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id
<UIViewControllerAnimatedTransitioning>)animator;
!
!
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id <UIViewControllerAnimatedTransitioning>)animator;
!
!
@end
@protocol UIViewControllerTransitioningDelegate <NSObject>
!
@optional
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting sourceController:
(UIViewController *)source;
!
!
- (id <UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController *)dismissed;
!
!
- (id
<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id
<UIViewControllerAnimatedTransitioning>)animator;
!
!
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id <UIViewControllerAnimatedTransitioning>)animator;
!
!
@end
UIViewController UIViewController
id <UIViewControllerTransitioningDelegate>
transitioningDelegate
animationControllerForPresentedController… animationControllerForDismissedController
id <UIViewControllerAnimatedTransitioning>
id <UIViewControllerAnimatedTransitioning>
present
dismiss
UIViewController UIViewController
id <UIViewControllerTransitioningDelegate>
transitioningDelegate
id <UIViewControllerAnimatedTransitioning>
id <UIViewControllerAnimatedTransitioning>
present
dismiss
id
<UIViewControllerInteractiveTra
nsitioning>
id
<UIViewControllerInteractiveTra
nsitioning>
id <UIViewControllerInteractiveTransitioning>
@protocol UIViewControllerInteractiveTransitioning <NSObject>
!
- (void)startInteractiveTransition:(id
<UIViewControllerContextTransitioning>)transitionContext;
!
@optional
!
- (CGFloat)completionSpeed;
- (UIViewAnimationCurve)completionCurve;
!
@end
UIPercentDrivenInteractiveTransition
UIPercentDrivenInteractiveTransition
- (void)updateInteractiveTransition:(CGFloat)percentComplete;
- (void)cancelInteractiveTransition;
- (void)finishInteractiveTransition;
CGFloat scale = [gestureRecognizer scale];
switch ([gestureRecognizer state]) {
case UIGestureRecognizerStateBegan:
transitionController.interactive = YES;
_startScale = scale;
[testViewController dismissViewControllerAnimated:YES completion:nil];
}
break;
case UIGestureRecognizerStateChanged: {
CGFloat percent = (1.0 - scale/_startScale);
[transitionController.percentDrivenInteractiveTransition updateInteractiveTransition: (percent <= 0.0) ? 0.0 :
percent];
break;
}
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
if ([gestureRecognizer velocity] >= 0.0 || [gestureRecognizer state] == UIGestureRecognizerStateCancelled) {
[transitionController.percentDrivenInteractiveTransition cancelInteractiveTransition];
}
else {
[transitionController.percentDrivenInteractiveTransition finishInteractiveTransition];
}
break;
default:
break;
}
CGFloat scale = [gestureRecognizer scale];
switch ([gestureRecognizer state]) {
case UIGestureRecognizerStateBegan:
transitionController.interactive = YES;
_startScale = scale;
[testViewController dismissViewControllerAnimated:YES completion:nil];
}
break;
case UIGestureRecognizerStateChanged: {
CGFloat percent = (1.0 - scale/_startScale);
[transitionController.percentDrivenInteractiveTransition updateInteractiveTransition: (percent <=
0.0) ? 0.0 : percent];
break;
}
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
if ([gestureRecognizer velocity] >= 0.0 || [gestureRecognizer state] == UIGestureRecognizerStateCancelled) {
[transitionController.percentDrivenInteractiveTransition cancelInteractiveTransition];
}
else {
[transitionController.percentDrivenInteractiveTransition finishInteractiveTransition];
}
break;
default:
break;
}
Core Animation!
!
+[UIView transitionFromView:toView:duration:options:completion:]!
!
Custom Animations!
!
UIView block-based animations
UIPercentDrivenInteractiveTransition
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:YES];
}];
[UIView animateWithDuration:self.duration
delay:0.0
options:0
animations:^{
toViewController.view.alpha = 1.0f;
}
completion:^(BOOL finished) {
[fromViewController.view removeFromSuperview];
[transitionContext completeTransition:
!transitionContext.transitionWasCancelled];
}];
- (void)startInteractiveTransition:(id
<UIViewControllerContextTransitioning>)transitionContext {
!
_transitionContext = transitionContext;
_toViewController = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
_toViewController.view.alpha = 0.0f;
_toViewController.view.frame = [transitionContext
finalFrameForViewController:_toViewController];
[transitionContext.containerView addSubview:_toViewController.view];
}
id <UIViewControllerInteractiveTransitioning>
id <UIViewControllerInteractiveTransitioning>
- (void)updateInteractiveTransition:(CGFloat)percentComplete {
_toViewController.view.alpha = percentComplete;
[_transitionContext updateInteractiveTransition:percentComplete];
}
id <UIViewControllerInteractiveTransitioning>
- (void)cancelInteractiveTransition {
[_transitionContext cancelInteractiveTransition];
[UIView animateWithDuration:0.3
delay:0.0
options:0
animations:^{
_toViewController.view.alpha = 0.0f;
}
completion:^(BOOL finished) {
[_transitionContext completeTransition:!
_transitionContext.transitionWasCancelled];
}];
}
viewWillAppear
viewDidAppear
viewWillDisappear
viewDidDisappear
viewWillAppear
viewDidAppear
viewWillDisappear
viewDidDisappear
viewWillAppear viewWillDisappear
viewDidDisappear
- (void)viewWillAppear:(BOOL)animated {
[self doSomeSideEffectsAssumingViewDidAppearIsGoingToBeCalled];
id <UIViewControllerTransitionCoordinator> coordinator;
coordinator = [self transitionCoordinator];
if(coordinator && [coordinator initiallyInteractive]) {
[transitionCoordinator notifyWhenInteractionEndsUsingBlock:
^(id <UIViewControllerTransitionCoordinatorContext> ctx) {
if(ctx.isCancelled) {
[self undoSideEffects];
}
}];
}
}
UIViewControllerTransitionCoordinator
UINavigationController
– pushViewController:animated:
– popViewControllerAnimated:
– popToRootViewControllerAnimated:
– popToViewController:animated:
- (id<UIViewControllerAnimatedTransitioning>)!
navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC !
toViewController:(UIViewController *)toVC
UINavigationControllerDelegate
- (id<UIViewControllerInteractiveTransitioning>)!
navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:
(id<UIViewControllerAnimatedTransitioning>)animationController
UINavigationController
@property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer
UITabBarController
@property(nonatomic, assign) UIViewController *selectedViewController
@property(nonatomic) NSUInteger selectedIndex
UITabBarControllerDelegate
- (id <UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController;
!
- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
animationControllerForTransitionFromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC;
finty fň
// Snapshot
UIView *fromView = [fromViewController.view snapshotViewAfterScreenUpdates:NO];
!
// Interactivity
fromViewController.view.userInteractionEnabled = NO;
toViewController.view.userInteractionEnabled = YES;
transitionContext.containerView.userInteractionEnabled = YES;
!
[transitionContext.containerView addSubview:fromView];
[transitionContext.containerView addSubview:toViewController.view];
!
// Finish before animation
[transitionContext completeTransition:YES];
!
[UIView animateWithDuration: . . .
// Prepare BitmapContext
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
GLubyte *textureData = malloc(textureWidth * textureHeight * 4);
memset_pattern4(textureData, "0000", textureWidth * textureHeight * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * textureWidth;
NSUInteger bitsPerComponent = 8;
CGContextRef bitmapContext = CGBitmapContextCreate(textureData, textureWidth,
textureHeight, bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
// draw
[view.layer renderInContext:bitmapContext];
CGContextRelease(bitmapContext);
!
// set data for texture
glBindTexture(GL_TEXTURE_2D, texture);
// set bitmap data into texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData);
// Don't need this data anymore
free(textureData);
fuck off view controllers
Custom UIViewController
Transitions
Ján Ilavský - @split82

More Related Content

Similar to Custom UIViewController Transitions

Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupNatasha Murashev
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder BehindJohn Wilker
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to SwiftElmar Kretzer
 
Quick Start to iOS Development
Quick Start to iOS DevelopmentQuick Start to iOS Development
Quick Start to iOS DevelopmentJussi Pohjolainen
 
Creating Container View Controllers
Creating Container View ControllersCreating Container View Controllers
Creating Container View ControllersBob McCune
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose worldFabio Collini
 
Intro to UIKit • Made by Many
Intro to UIKit • Made by ManyIntro to UIKit • Made by Many
Intro to UIKit • Made by Manykenatmxm
 
ios_summit_2016_korhan
ios_summit_2016_korhanios_summit_2016_korhan
ios_summit_2016_korhanKorhan Bircan
 
There is no spoon - iPhone vs. iPad
There is no spoon - iPhone vs. iPadThere is no spoon - iPhone vs. iPad
There is no spoon - iPhone vs. iPadPaul Ardeleanu
 
Константин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsКонстантин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsGeeksLab Odessa
 
iOSインタラクションデザイン
iOSインタラクションデザインiOSインタラクションデザイン
iOSインタラクションデザインhIDDENxv
 
Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1Noriyuki Nonomura
 
Projet d'accès aux résultats des étudiant via client mobile
Projet d'accès aux résultats des étudiant via client mobile Projet d'accès aux résultats des étudiant via client mobile
Projet d'accès aux résultats des étudiant via client mobile Patrick Bashizi
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM patternNAVER Engineering
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfssuserb6c2641
 

Similar to Custom UIViewController Transitions (20)

Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
iOS
iOSiOS
iOS
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
SwiftでUIKitDynamics
SwiftでUIKitDynamicsSwiftでUIKitDynamics
SwiftでUIKitDynamics
 
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
 
Quick Start to iOS Development
Quick Start to iOS DevelopmentQuick Start to iOS Development
Quick Start to iOS Development
 
Protocol-Oriented MVVM
Protocol-Oriented MVVMProtocol-Oriented MVVM
Protocol-Oriented MVVM
 
Creating Container View Controllers
Creating Container View ControllersCreating Container View Controllers
Creating Container View Controllers
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
004
004004
004
 
Intro to UIKit • Made by Many
Intro to UIKit • Made by ManyIntro to UIKit • Made by Many
Intro to UIKit • Made by Many
 
ios_summit_2016_korhan
ios_summit_2016_korhanios_summit_2016_korhan
ios_summit_2016_korhan
 
There is no spoon - iPhone vs. iPad
There is no spoon - iPhone vs. iPadThere is no spoon - iPhone vs. iPad
There is no spoon - iPhone vs. iPad
 
Константин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windowsКонстантин Чернухо_Popups, alerts and windows
Константин Чернухо_Popups, alerts and windows
 
iOSインタラクションデザイン
iOSインタラクションデザインiOSインタラクションデザイン
iOSインタラクションデザイン
 
Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1
 
iOS_Presentation
iOS_PresentationiOS_Presentation
iOS_Presentation
 
Projet d'accès aux résultats des étudiant via client mobile
Projet d'accès aux résultats des étudiant via client mobile Projet d'accès aux résultats des étudiant via client mobile
Projet d'accès aux résultats des étudiant via client mobile
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
 

Recently uploaded

Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesKrzysztofKkol1
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEJelle | Nordend
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...rajkumar669520
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAlluxio, Inc.
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...Alluxio, Inc.
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownloadvrstrong314
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfkalichargn70th171
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion Clinic
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessWSO2
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfMeon Technology
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfmbmh111980
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1KnowledgeSeed
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisNeo4j
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfOrtus Solutions, Corp
 

Recently uploaded (20)

Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysis
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 

Custom UIViewController Transitions