SlideShare une entreprise Scribd logo
1  sur  83
Télécharger pour lire hors ligne
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

Contenu connexe

Similaire à Custom UIViewController Transitions

Quick Start to iOS Development
Quick Start to iOS DevelopmentQuick Start to iOS Development
Quick Start to iOS Development
Jussi Pohjolainen
 
ios_summit_2016_korhan
ios_summit_2016_korhanios_summit_2016_korhan
ios_summit_2016_korhan
Korhan Bircan
 
Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Heat on Wed.(ヒートオンウェンズディ)! Vol.1
Noriyuki Nonomura
 
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdfCompose로 Android:Desktop 멀티플랫폼 만들기.pdf
Compose로 Android:Desktop 멀티플랫폼 만들기.pdf
ssuserb6c2641
 

Similaire à 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
 

Dernier

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Dernier (20)

%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
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
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 

Custom UIViewController Transitions