├── CodeSnapshot
├── 01.png
├── 02.png
├── 03.png
├── 04.png
├── 05.png
├── 06.png
├── 07.png
├── 08.png
├── 09.png
├── 10.png
├── 11.png
├── 12.png
├── 13.png
├── 14.png
├── 15.png
├── 16.png
├── 17.png
├── 18.png
├── 19.png
├── 20.png
├── 21.png
├── 22.png
├── 23.png
├── 24.png
├── 25.png
├── 26.png
├── 27.png
├── 28.png
├── 29.png
└── 30.png
├── Figures
├── Push&Pop.gif
├── AlipayDonate.png
├── MaskAnimtion.gif
├── ModalTransition.gif
├── SlideAnimation.gif
├── ContainerVC VS Modal.png
├── ContainerVCTransition.mov.gif
├── Reference in Transition.png
├── The Anatomy of Transition.png
├── Truth behind BubbleTransition.gif
├── CustomContainerVCButtonTransition.gif
└── Reference in Transition with Interactor.png
├── ScrollTabBarController
├── ScrollTabBarController
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Icon.png
│ │ │ ├── Icon@2x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ ├── Icon-Spotlight-40@2x-1.png
│ │ │ ├── Icon-Spotlight-40@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_me.imageset
│ │ │ ├── tabbar_me@2x.png
│ │ │ ├── tabbar_me@3x.png
│ │ │ └── Contents.json
│ │ ├── LaunchImage.launchimage
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@2x-1.png
│ │ │ ├── LaunchImage-568h@2x.png
│ │ │ ├── LaunchImage-568h@2x-1.png
│ │ │ ├── LaunchImage-800-667h@2x.png
│ │ │ ├── LaunchImage-800-Portrait-736h@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_meHL.imageset
│ │ │ ├── tabbar_meHL@2x.png
│ │ │ ├── tabbar_meHL@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_contacts.imageset
│ │ │ ├── tabbar_contacts@2x.png
│ │ │ ├── tabbar_contacts@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_discover.imageset
│ │ │ ├── tabbar_discover@2x.png
│ │ │ ├── tabbar_discover@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_wechat.imageset
│ │ │ ├── tabbar_mainframe@2x.png
│ │ │ ├── tabbar_mainframe@3x.png
│ │ │ └── Contents.json
│ │ ├── barbuttonicon_add.imageset
│ │ │ ├── barbuttonicon_add.png
│ │ │ ├── barbuttonicon_add@2x.png
│ │ │ ├── barbuttonicon_add@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_wechatHL.imageset
│ │ │ ├── tabbar_mainframeHL@2x.png
│ │ │ ├── tabbar_mainframeHL@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_contactsHL.imageset
│ │ │ ├── tabbar_contactsHL@2x.png
│ │ │ ├── tabbar_contactsHL@3x.png
│ │ │ └── Contents.json
│ │ ├── tabbar_discoverHL.imageset
│ │ │ ├── tabbar_discoverHL@2x.png
│ │ │ ├── tabbar_discoverHL@3x.png
│ │ │ └── Contents.json
│ │ └── Brand Assets.launchimage
│ │ │ └── Contents.json
│ ├── ViewController.swift
│ ├── SDETabBarVCDelegate.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── AppDelegate.swift
│ ├── ScrollTabBarController.swift
│ └── SlideAnimationController.swift
└── ScrollTabBarController.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ └── seedante.xcuserdatad
│ ├── xcschemes
│ ├── xcschememanagement.plist
│ └── ScrollTabBarController.xcscheme
│ └── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
├── iOS10PushPop
├── iOS10PushPop.xcodeproj
│ ├── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── iOS10PushPop.xcscheme
│ └── project.xcworkspace
│ │ ├── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── contents.xcworkspacedata
└── InterruptibleTransition
│ ├── ViewController.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── AppDelegate.swift
│ ├── SDENavigationDelegate.swift
│ └── InterruptibleNavigationController.swift
├── CustomModalTransition
├── CustomModalTransitionDemo.xcodeproj
│ ├── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── CustomModalTransition.xcscheme
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── CustomModalTransition
│ ├── SDEModalTransitionDelegate.swift
│ ├── PresentingViewController.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── OverlayPresentationController.swift
│ ├── PresentedViewController.swift
│ ├── AppDelegate.swift
│ ├── OverlayAnimationController.swift
│ └── SlideAnimationController.swift
├── NavigationControllerTransition
├── NavigationControllerTransitionDemo.xcodeproj
│ ├── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── NavigationControllerTransitionDemo.xcscheme
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── NavigationControllerTransitionDemo
│ ├── PushViewController.swift
│ ├── SDENavigationDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── AppDelegate.swift
│ ├── PopViewController.swift
│ └── SlideAnimationController.swift
├── CustomContainerVCTransition
├── CustomContainerVCTransition.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── seedante.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── CustomContainerVCTransition.xcscheme
└── CustomContainerVCTransition
│ ├── ViewController.swift
│ ├── SDEPercentDrivenInteractiveTransition.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── AppDelegate.swift
│ ├── ContainerTransitionDelegate.swift
│ ├── SDETabBarViewController.swift
│ └── SlideAnimationController.swift
├── CollectionViewControllerLayoutTransition
├── CollectionViewControllerLayoutTransition.xcodeproj
│ ├── project.xcworkspace
│ │ ├── xcuserdata
│ │ │ └── seedante.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── seedante.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── CollectionVCLayoutTransition.xcscheme
└── CollectionViewControllerLayoutTransition
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── CollectionVCTestOne.swift
│ └── CollectionVCTestTwo.swift
└── README.md
/CodeSnapshot/01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/01.png
--------------------------------------------------------------------------------
/CodeSnapshot/02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/02.png
--------------------------------------------------------------------------------
/CodeSnapshot/03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/03.png
--------------------------------------------------------------------------------
/CodeSnapshot/04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/04.png
--------------------------------------------------------------------------------
/CodeSnapshot/05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/05.png
--------------------------------------------------------------------------------
/CodeSnapshot/06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/06.png
--------------------------------------------------------------------------------
/CodeSnapshot/07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/07.png
--------------------------------------------------------------------------------
/CodeSnapshot/08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/08.png
--------------------------------------------------------------------------------
/CodeSnapshot/09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/09.png
--------------------------------------------------------------------------------
/CodeSnapshot/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/10.png
--------------------------------------------------------------------------------
/CodeSnapshot/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/11.png
--------------------------------------------------------------------------------
/CodeSnapshot/12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/12.png
--------------------------------------------------------------------------------
/CodeSnapshot/13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/13.png
--------------------------------------------------------------------------------
/CodeSnapshot/14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/14.png
--------------------------------------------------------------------------------
/CodeSnapshot/15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/15.png
--------------------------------------------------------------------------------
/CodeSnapshot/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/16.png
--------------------------------------------------------------------------------
/CodeSnapshot/17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/17.png
--------------------------------------------------------------------------------
/CodeSnapshot/18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/18.png
--------------------------------------------------------------------------------
/CodeSnapshot/19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/19.png
--------------------------------------------------------------------------------
/CodeSnapshot/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/20.png
--------------------------------------------------------------------------------
/CodeSnapshot/21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/21.png
--------------------------------------------------------------------------------
/CodeSnapshot/22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/22.png
--------------------------------------------------------------------------------
/CodeSnapshot/23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/23.png
--------------------------------------------------------------------------------
/CodeSnapshot/24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/24.png
--------------------------------------------------------------------------------
/CodeSnapshot/25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/25.png
--------------------------------------------------------------------------------
/CodeSnapshot/26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/26.png
--------------------------------------------------------------------------------
/CodeSnapshot/27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/27.png
--------------------------------------------------------------------------------
/CodeSnapshot/28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/28.png
--------------------------------------------------------------------------------
/CodeSnapshot/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/29.png
--------------------------------------------------------------------------------
/CodeSnapshot/30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CodeSnapshot/30.png
--------------------------------------------------------------------------------
/Figures/Push&Pop.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/Push&Pop.gif
--------------------------------------------------------------------------------
/Figures/AlipayDonate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/AlipayDonate.png
--------------------------------------------------------------------------------
/Figures/MaskAnimtion.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/MaskAnimtion.gif
--------------------------------------------------------------------------------
/Figures/ModalTransition.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/ModalTransition.gif
--------------------------------------------------------------------------------
/Figures/SlideAnimation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/SlideAnimation.gif
--------------------------------------------------------------------------------
/Figures/ContainerVC VS Modal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/ContainerVC VS Modal.png
--------------------------------------------------------------------------------
/Figures/ContainerVCTransition.mov.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/ContainerVCTransition.mov.gif
--------------------------------------------------------------------------------
/Figures/Reference in Transition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/Reference in Transition.png
--------------------------------------------------------------------------------
/Figures/The Anatomy of Transition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/The Anatomy of Transition.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Figures/Truth behind BubbleTransition.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/Truth behind BubbleTransition.gif
--------------------------------------------------------------------------------
/Figures/CustomContainerVCButtonTransition.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/CustomContainerVCButtonTransition.gif
--------------------------------------------------------------------------------
/Figures/Reference in Transition with Interactor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/Figures/Reference in Transition with Interactor.png
--------------------------------------------------------------------------------
/iOS10PushPop/iOS10PushPop.xcodeproj/xcuserdata/seedante.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_me.imageset/tabbar_me@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_me.imageset/tabbar_me@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_me.imageset/tabbar_me@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_me.imageset/tabbar_me@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_meHL.imageset/tabbar_meHL@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_meHL.imageset/tabbar_meHL@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_meHL.imageset/tabbar_meHL@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_meHL.imageset/tabbar_meHL@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x-1.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage@2x-1.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-568h@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contacts.imageset/tabbar_contacts@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contacts.imageset/tabbar_contacts@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contacts.imageset/tabbar_contacts@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contacts.imageset/tabbar_contacts@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discover.imageset/tabbar_discover@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discover.imageset/tabbar_discover@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discover.imageset/tabbar_discover@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discover.imageset/tabbar_discover@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechat.imageset/tabbar_mainframe@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechat.imageset/tabbar_mainframe@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechat.imageset/tabbar_mainframe@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechat.imageset/tabbar_mainframe@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-568h@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-568h@2x-1.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechatHL.imageset/tabbar_mainframeHL@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechatHL.imageset/tabbar_mainframeHL@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechatHL.imageset/tabbar_mainframeHL@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechatHL.imageset/tabbar_mainframeHL@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-800-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-800-667h@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/barbuttonicon_add@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contactsHL.imageset/tabbar_contactsHL@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contactsHL.imageset/tabbar_contactsHL@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contactsHL.imageset/tabbar_contactsHL@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contactsHL.imageset/tabbar_contactsHL@3x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discoverHL.imageset/tabbar_discoverHL@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discoverHL.imageset/tabbar_discoverHL@2x.png
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discoverHL.imageset/tabbar_discoverHL@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discoverHL.imageset/tabbar_discoverHL@3x.png
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS10PushPop/iOS10PushPop.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/iOS10PushPop/iOS10PushPop.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-800-Portrait-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/LaunchImage-800-Portrait-736h@3x.png
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS10PushPop/iOS10PushPop.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/ScrollTabBarController/ScrollTabBarController.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CustomContainerVCTransition/CustomContainerVCTransition.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seedante/iOS-ViewController-Transition-Demo/HEAD/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/project.xcworkspace/xcuserdata/seedante.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_me.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_me@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_me@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_meHL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_meHL@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_meHL@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discover.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_discover@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_discover@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechat.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_mainframe@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_mainframe@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contactsHL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_contactsHL@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_contactsHL@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_discoverHL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_discoverHL@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_discoverHL@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_wechatHL.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_mainframeHL@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_mainframeHL@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/barbuttonicon_add.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "barbuttonicon_add.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "barbuttonicon_add@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "barbuttonicon_add@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/tabbar_contacts.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tabbar_contacts@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tabbar_contacts@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | },
22 | "properties" : {
23 | "template-rendering-intent" : "template"
24 | }
25 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ScrollTabBarController
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/iOS10PushPop/iOS10PushPop.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | iOS10PushPop.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD8D55E81C187C01001143EA
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/xcuserdata/seedante.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CollectionVCLayoutTransitionDemo
4 | //
5 | // Created by seedante on 15/12/23.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CustomModalTransition.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD368ACD1C1F26C9001D204F
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ScrollTabBarController.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD8D55C81C1825AB001143EA
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CustomContainerVCTransition.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD8AFED71C2B2A93008EC7F9
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/PushViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PushViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 |
19 | override func didReceiveMemoryWarning() {
20 | super.didReceiveMemoryWarning()
21 | // Dispose of any resources that can be recreated.
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | NavigationControllerTransitionDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD8D55E81C187C01001143EA
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CollectionVCLayoutTransition.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FD8AFEB11C2AD954008EC7F9
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // iOS10PushPop
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 | convenience init(red: Int, green: Int, blue: Int) {
13 | assert(red >= 0 && red <= 255, "Invalid red component")
14 | assert(green >= 0 && green <= 255, "Invalid green component")
15 | assert(blue >= 0 && blue <= 255, "Invalid blue component")
16 |
17 | self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
18 | }
19 |
20 | convenience init(netHex:Int) {
21 | self.init(red:(netHex >> 16) & 0xff, green:(netHex >> 8) & 0xff, blue:netHex & 0xff)
22 | }
23 | }
24 |
25 | class ViewController: UIViewController {
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | view.backgroundColor = UIColor(netHex: 0x007AFF)
30 |
31 | }
32 |
33 | @IBAction func pop(_ sender: AnyObject) {
34 | _ = self.navigationController?.popViewController(animated: true)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/SDENavigationDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationControllerDelegate.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SDENavigationDelegate: NSObject, UINavigationControllerDelegate {
12 |
13 | var interactive = false
14 | let interactionController = UIPercentDrivenInteractiveTransition()
15 |
16 | func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
17 | let transitionType = SDETransitionType.navigationTransition(operation)
18 | return SlideAnimationController(type: transitionType)
19 | }
20 |
21 | func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?{
22 | return interactive ? self.interactionController : nil
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CustomContainerVCTransition
4 | //
5 | // Created by seedante on 15/12/24.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | let label = UILabel()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | // Do any additional setup after loading the view, typically from a nib.
18 | }
19 |
20 | override func viewWillAppear(_ animated: Bool) {
21 | super.viewWillAppear(animated)
22 | if label.superview == nil{
23 | label.text = title
24 | label.sizeToFit()
25 | view.addSubview(label)
26 |
27 | label.translatesAutoresizingMaskIntoConstraints = false
28 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .centerX, relatedBy: .equal, toItem: label, attribute: .centerX, multiplier: 1, constant: 0))
29 | view.addConstraint(NSLayoutConstraint(item: view, attribute: .centerY, relatedBy: .equal, toItem: label, attribute: .centerY, multiplier: 1, constant: 0))
30 | }
31 |
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/Brand Assets.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "ipad",
6 | "minimum-system-version" : "7.0",
7 | "extent" : "full-screen",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "landscape",
12 | "idiom" : "ipad",
13 | "minimum-system-version" : "7.0",
14 | "extent" : "full-screen",
15 | "scale" : "1x"
16 | },
17 | {
18 | "orientation" : "landscape",
19 | "idiom" : "ipad",
20 | "minimum-system-version" : "7.0",
21 | "extent" : "full-screen",
22 | "scale" : "2x"
23 | },
24 | {
25 | "orientation" : "portrait",
26 | "idiom" : "iphone",
27 | "minimum-system-version" : "7.0",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "minimum-system-version" : "7.0",
34 | "subtype" : "retina4",
35 | "scale" : "2x"
36 | },
37 | {
38 | "orientation" : "portrait",
39 | "idiom" : "ipad",
40 | "minimum-system-version" : "7.0",
41 | "extent" : "full-screen",
42 | "scale" : "1x"
43 | }
44 | ],
45 | "info" : {
46 | "version" : 1,
47 | "author" : "xcode"
48 | }
49 | }
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/SDEPercentDrivenInteractiveTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SDEPercentDrivenInteractiveTransition.swift
3 | // CustomContainerVCTransition
4 | //
5 | // Created by seedante on 15/12/27.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SDEPercentDrivenInteractiveTransition: NSObject, UIViewControllerInteractiveTransitioning {
12 |
13 | weak var containerTransitionContext: ContainerTransitionContext?
14 |
15 | func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
16 | if let context = transitionContext as? ContainerTransitionContext{
17 | containerTransitionContext = context
18 | containerTransitionContext?.activateInteractiveTransition()
19 | }else{
20 | fatalError("\(transitionContext) is not class or subclass of ContainerTransitionContext")
21 | }
22 | }
23 |
24 | func updateInteractiveTransition(_ percentComplete: CGFloat){
25 | containerTransitionContext?.updateInteractiveTransition(percentComplete)
26 | }
27 |
28 | func cancelInteractiveTransition(){
29 | containerTransitionContext?.cancelInteractiveTransition()
30 | }
31 |
32 | func finishInteractiveTransition(){
33 | containerTransitionContext?.finishInteractiveTransition()
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/SDEModalTransitionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PresentTransitionDelegate.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/17.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SDEModalTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
12 |
13 | func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
14 | return OverlayAnimationController()
15 | //Or
16 | // let transitionType = SDETransitionType.modalTransition(.presentation)
17 | // return SlideAnimationController(type: transitionType)
18 | }
19 |
20 | func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
21 | return OverlayAnimationController()
22 | //Or
23 | // let transitionType = SDETransitionType.modalTransition(.dismissal)
24 | // return SlideAnimationController(type: transitionType)
25 | }
26 |
27 | func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
28 | return OverlayPresentationController(presentedViewController: presented, presenting: presenting)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/SDETabBarVCDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SDETabBarControllerDelegate.swift
3 | // ScrollTabBarController
4 | //
5 | // Created by seedante on 15/12/20.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SDETabBarVCDelegate: NSObject, UITabBarControllerDelegate {
12 |
13 | var interactive = false
14 | let interactionController = UIPercentDrivenInteractiveTransition()
15 |
16 | func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
17 | let fromIndex = tabBarController.viewControllers!.index(of: fromVC)!
18 | let toIndex = tabBarController.viewControllers!.index(of: toVC)!
19 |
20 | let tabChangeDirection: TabOperationDirection = toIndex < fromIndex ? TabOperationDirection.left : TabOperationDirection.right
21 | let transitionType = SDETransitionType.tabTransition(tabChangeDirection)
22 | let slideAnimationController = SlideAnimationController(type: transitionType)
23 | return slideAnimationController
24 | }
25 |
26 | func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?{
27 | return interactive ? interactionController : nil
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/PresentingViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PresentingViewController.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/15.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PresentingViewController: UIViewController{
12 |
13 | let presentTransitionDelegate = SDEModalTransitionDelegate()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | // Do any additional setup after loading the view.
18 |
19 | }
20 |
21 | override func didReceiveMemoryWarning() {
22 | super.didReceiveMemoryWarning()
23 | // Dispose of any resources that can be recreated.
24 | }
25 |
26 | /*
27 | .FullScreen 的时候,presentingView 的移除和添加由 UIKit 负责,在 presentation 转场结束后被移除,dismissal 转场结束时重新回到原来的位置;
28 | .Custom 的时候,presentingView 依然由 UIKit 负责,但 presentation 转场结束后不会被移除。
29 | */
30 |
31 | // In a storyboard-based application, you will often want to do a little preparation before navigation
32 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
33 | // Get the new view controller using segue.destinationViewController.
34 | // Pass the selected object to the new view controller.
35 | let toVC = segue.destination as! PresentedViewController
36 | toVC.transitioningDelegate = presentTransitionDelegate
37 | toVC.modalPresentationStyle = .custom
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "size" : "29x29",
15 | "idiom" : "iphone",
16 | "filename" : "Icon-Small.png",
17 | "scale" : "1x"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "iphone",
22 | "filename" : "Icon-Small@2x.png",
23 | "scale" : "2x"
24 | },
25 | {
26 | "size" : "29x29",
27 | "idiom" : "iphone",
28 | "filename" : "Icon-Small@3x.png",
29 | "scale" : "3x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "iphone",
34 | "filename" : "Icon-Spotlight-40@2x-1.png",
35 | "scale" : "2x"
36 | },
37 | {
38 | "size" : "40x40",
39 | "idiom" : "iphone",
40 | "filename" : "Icon-Spotlight-40@3x.png",
41 | "scale" : "3x"
42 | },
43 | {
44 | "size" : "57x57",
45 | "idiom" : "iphone",
46 | "filename" : "Icon.png",
47 | "scale" : "1x"
48 | },
49 | {
50 | "size" : "57x57",
51 | "idiom" : "iphone",
52 | "filename" : "Icon@2x.png",
53 | "scale" : "2x"
54 | },
55 | {
56 | "size" : "60x60",
57 | "idiom" : "iphone",
58 | "filename" : "Icon-60@2x.png",
59 | "scale" : "2x"
60 | },
61 | {
62 | "size" : "60x60",
63 | "idiom" : "iphone",
64 | "filename" : "Icon-60@3x.png",
65 | "scale" : "3x"
66 | }
67 | ],
68 | "info" : {
69 | "version" : 1,
70 | "author" : "xcode"
71 | }
72 | }
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | PUSH&POP
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/OverlayPresentationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OverlayPresentationController.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/17.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class OverlayPresentationController: UIPresentationController {
12 | let dimmingView = UIView()
13 |
14 | override func presentationTransitionWillBegin() {
15 | containerView?.addSubview(dimmingView)
16 |
17 | let dimmingViewInitailWidth = containerView!.frame.width * 2 / 3, dimmingViewInitailHeight = containerView!.frame.height * 2 / 3
18 | dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
19 | dimmingView.center = containerView!.center
20 | dimmingView.bounds = CGRect(x: 0, y: 0, width: dimmingViewInitailWidth , height: dimmingViewInitailHeight)
21 |
22 | _ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: {
23 | _ in
24 | self.dimmingView.bounds = self.containerView!.bounds
25 | }, completion: nil)
26 | }
27 |
28 | override func dismissalTransitionWillBegin() {
29 | _ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in
30 | self.dimmingView.alpha = 0.0
31 | }, completion: nil)
32 | }
33 |
34 | override func containerViewWillLayoutSubviews(){
35 | dimmingView.center = containerView!.center
36 | dimmingView.bounds = containerView!.bounds
37 |
38 | let width = containerView!.frame.width * 2 / 3, height = containerView!.frame.height * 2 / 3
39 | presentedView?.center = containerView!.center
40 | presentedView?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CustomContainerVCTransition
4 | //
5 | // Created by seedante on 15/12/24.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 | var containerVCDelegate: SDEContainerViewControllerDelegate?
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | window = UIWindow(frame: UIScreen.main.bounds)
20 | window?.rootViewController = configureRootViewController()
21 | window?.makeKeyAndVisible()
22 | return true
23 | }
24 |
25 | func configureRootViewController() -> UIViewController{
26 |
27 | let subVC0 = ViewController()
28 | subVC0.view.backgroundColor = UIColor(red: 0.4, green: 0.8, blue: 1, alpha: 1)
29 | subVC0.title = "DC"
30 | let subVC1 = ViewController()
31 | subVC1.view.backgroundColor = UIColor(red: 0.1, green: 0.4, blue: 0.8, alpha: 1)
32 | subVC1.title = "Marvel"
33 | let subVC2 = ViewController()
34 | subVC2.view.backgroundColor = UIColor(red: 0.3, green: 0.8, blue: 0.4, alpha: 1)
35 | subVC2.title = "DHC"
36 | let subVC3 = ViewController()
37 | subVC3.view.backgroundColor = UIColor(red: 0.5, green: 0.4, blue: 0.5, alpha: 1)
38 | subVC3.title = "Image"
39 |
40 | let containerController = SDETabBarViewController(viewControllers: [subVC0 ,subVC1, subVC2, subVC3])
41 | containerVCDelegate = SDEContainerViewControllerDelegate()
42 | containerController.containerTransitionDelegate = containerVCDelegate
43 |
44 | return containerController
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "LaunchImage-800-Portrait-736h@3x.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "orientation" : "landscape",
14 | "idiom" : "iphone",
15 | "extent" : "full-screen",
16 | "minimum-system-version" : "8.0",
17 | "subtype" : "736h",
18 | "scale" : "3x"
19 | },
20 | {
21 | "extent" : "full-screen",
22 | "idiom" : "iphone",
23 | "subtype" : "667h",
24 | "filename" : "LaunchImage-800-667h@2x.png",
25 | "minimum-system-version" : "8.0",
26 | "orientation" : "portrait",
27 | "scale" : "2x"
28 | },
29 | {
30 | "orientation" : "portrait",
31 | "idiom" : "iphone",
32 | "filename" : "LaunchImage@2x.png",
33 | "extent" : "full-screen",
34 | "minimum-system-version" : "7.0",
35 | "scale" : "2x"
36 | },
37 | {
38 | "extent" : "full-screen",
39 | "idiom" : "iphone",
40 | "subtype" : "retina4",
41 | "filename" : "LaunchImage-568h@2x.png",
42 | "minimum-system-version" : "7.0",
43 | "orientation" : "portrait",
44 | "scale" : "2x"
45 | },
46 | {
47 | "orientation" : "portrait",
48 | "idiom" : "iphone",
49 | "filename" : "LaunchImage.png",
50 | "extent" : "full-screen",
51 | "scale" : "1x"
52 | },
53 | {
54 | "orientation" : "portrait",
55 | "idiom" : "iphone",
56 | "filename" : "LaunchImage@2x-1.png",
57 | "extent" : "full-screen",
58 | "scale" : "2x"
59 | },
60 | {
61 | "orientation" : "portrait",
62 | "idiom" : "iphone",
63 | "filename" : "LaunchImage-568h@2x-1.png",
64 | "extent" : "full-screen",
65 | "subtype" : "retina4",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/PresentedViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/15.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PresentedViewController: UIViewController{
12 |
13 | let presentTransitionDelegate = SDEModalTransitionDelegate()
14 | @IBOutlet weak var dismissButton: UIButton!
15 | @IBOutlet weak var inputTextField: UITextField!
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | dismissButton.alpha = 0
20 | // Do any additional setup after loading the view, typically from a nib.
21 | }
22 |
23 | override func didReceiveMemoryWarning() {
24 | super.didReceiveMemoryWarning()
25 | // Dispose of any resources that can be recreated.
26 | }
27 |
28 | override func viewDidAppear(_ animated: Bool) {
29 | super.viewDidAppear(animated)
30 | let widthContraint = inputTextField.constraints.filter({constraint in
31 | constraint.identifier == "Width"
32 | }).first
33 | widthContraint?.constant = view.frame.width * 2 / 3
34 |
35 | UIView.animate(withDuration: 0.3, animations: {
36 | self.dismissButton.alpha = 1
37 | self.view.layoutIfNeeded()
38 | })
39 | }
40 |
41 | @IBAction func dismiss(_ sender: AnyObject) {
42 | var applyTransform = CGAffineTransform( rotationAngle: 3 * CGFloat(M_PI))
43 | applyTransform = applyTransform.scaledBy(x: 0.1, y: 0.1)
44 |
45 | let widthContraint = inputTextField.constraints.filter({constraint in
46 | constraint.identifier == "Width"
47 | }).first
48 | widthContraint?.constant = 0
49 |
50 | UIView.animate(withDuration: 0.4, animations: {
51 | self.dismissButton.transform = applyTransform
52 | self.view.layoutIfNeeded()
53 | }, completion: { _ in
54 | self.dismiss(animated: true, completion: nil)
55 | })
56 |
57 | }
58 |
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/CollectionVCTestOne.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionViewController.swift
3 | // CollectionVCLayoutTransitionDemo
4 | //
5 | // Created by seedante on 15/12/23.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CollectionVCTestOne: UICollectionViewController {
12 |
13 | let reuseIdentifier = "Cell"
14 |
15 | override func viewDidAppear(_ animated: Bool) {
16 | super.viewDidAppear(animated)
17 | let count = self.navigationController!.viewControllers.count
18 | self.title = "Level \(count)"
19 | }
20 |
21 | /*
22 | 进行布局转场时,数据源的数量(section 和 cell 数量)要保持一致,尽管你可以在中途修改数量,但是回到最初的 CollectionViewController 时会出错。
23 | */
24 | // MARK: UICollectionViewDataSource
25 | override func numberOfSections(in collectionView: UICollectionView) -> Int {
26 | return 2
27 | }
28 |
29 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
30 | return 15
31 | }
32 |
33 |
34 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
35 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath)
36 | if indexPath.section == 0{
37 | cell.backgroundColor = UIColor.red
38 | }else{
39 | cell.backgroundColor = UIColor.brown
40 | }
41 |
42 | return cell
43 | }
44 |
45 | //MARK: UICollectionViewDelegate
46 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
47 | //根据点击 cell 的位置来决定下一级的 CollectionView 的布局
48 | let layout = UICollectionViewFlowLayout()
49 | layout.itemSize = CGSize(width: indexPath.item * 10, height: indexPath.item * 10)
50 | layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10)
51 | let nextCVC = CollectionVCTestOne(collectionViewLayout: layout)
52 | nextCVC.useLayoutToLayoutNavigationTransitions = true
53 | navigationController?.pushViewController(nextCVC, animated: true)
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ScrollTabBarController
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // iOS10PushPop
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/15.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/ContainerTransitionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContainerTransitionDelegate.swift
3 | // CustomContainerVCTransition
4 | //
5 | // Created by seedante on 15/12/26.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 | import UIKit
9 |
10 | @objc protocol ContainerViewControllerDelegate{
11 | //Swift don't support protocol object in protocol now. if you want to support interactive transition, set SDEContainerViewController's containerTransitionDelegate to class 'SDEContainerViewControllerDelegate', not protocol 'ContainerViewControllerDelegate'
12 | //var interactionController: UIViewControllerInteractiveTransitioning?
13 | func containerController(_ containerController: SDEContainerViewController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
14 | @objc optional func containerController(_ containerController: SDEContainerViewController, interactionControllerForAnimation animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
15 | }
16 |
17 | class SDEContainerViewControllerDelegate: NSObject, ContainerViewControllerDelegate {
18 |
19 | var interactionController = SDEPercentDrivenInteractiveTransition()
20 |
21 | func containerController(_ containerController: SDEContainerViewController, animationControllerForTransitionFromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
22 | let fromIndex = containerController.viewControllers!.index(of: fromVC)!
23 | let toIndex = containerController.viewControllers!.index(of: toVC)!
24 | let tabChangeDirection: TabOperationDirection = toIndex < fromIndex ? TabOperationDirection.left : TabOperationDirection.right
25 | let transitionType = SDETransitionType.tabTransition(tabChangeDirection)
26 | let slideAnimationController = SlideAnimationController(type: transitionType)
27 | return slideAnimationController
28 | }
29 |
30 | func containerController(_ containerController: SDEContainerViewController, interactionControllerForAnimation animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
31 | return interactionController
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | @nonobjc func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/PopViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopViewController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PopViewController: UIViewController {
12 |
13 | let edgePanGesture = UIScreenEdgePanGestureRecognizer()
14 | var navigationDelegate: SDENavigationDelegate?
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | navigationItem.title = "StackTop"
19 | // Do any additional setup after loading the view.
20 | edgePanGesture.edges = .left
21 | edgePanGesture.addTarget(self, action: #selector(PopViewController.handleEdgePanGesture(gesture:)))
22 | view.addGestureRecognizer(edgePanGesture)
23 | }
24 |
25 | override func didReceiveMemoryWarning() {
26 | super.didReceiveMemoryWarning()
27 | // Dispose of any resources that can be recreated.
28 | }
29 |
30 | func handleEdgePanGesture(gesture: UIScreenEdgePanGestureRecognizer){
31 | let translationX = gesture.translation(in: view).x
32 | let translationBase: CGFloat = view.frame.width / 3
33 | let translationAbs = translationX > 0 ? translationX : -translationX
34 | let percent = translationAbs > translationBase ? 1.0 : translationAbs / translationBase
35 | switch gesture.state{
36 | case .began:
37 | navigationDelegate = self.navigationController?.delegate as? SDENavigationDelegate
38 | navigationDelegate?.interactive = true
39 | _ = self.navigationController?.popViewController(animated: true)
40 | case .changed:
41 | navigationDelegate?.interactionController.update(percent)
42 | case .cancelled, .ended:
43 | if percent > 0.5{
44 | navigationDelegate?.interactionController.finish()
45 | }else{
46 | navigationDelegate?.interactionController.cancel()
47 | }
48 | navigationDelegate?.interactive = false
49 | default: break
50 | }
51 | }
52 |
53 | @IBAction func popMe(_ sender: Any) {
54 | _ = navigationController?.popViewController(animated: true)
55 | }
56 |
57 | deinit{
58 | edgePanGesture.removeTarget(self, action: #selector(PopViewController.handleEdgePanGesture(gesture:)))
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/SDETabBarViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SDETabBarViewController.swift
3 | // CustomContainerVCTransition
4 | //
5 | // Created by seedante on 15/12/29.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | // FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
11 | // Consider refactoring the code to use the non-optional operators.
12 | fileprivate func < (lhs: T?, rhs: T?) -> Bool {
13 | switch (lhs, rhs) {
14 | case let (l?, r?):
15 | return l < r
16 | case (nil, _?):
17 | return true
18 | default:
19 | return false
20 | }
21 | }
22 |
23 |
24 | class SDETabBarViewController: SDEContainerViewController {
25 |
26 | override func viewDidLoad() {
27 | super.viewDidLoad()
28 | //Configure Interactive Transiton
29 | let pangesture = UIPanGestureRecognizer(target: self, action: #selector(SDETabBarViewController.handlePan(_:)))
30 | view.addGestureRecognizer(pangesture)
31 | }
32 |
33 | func handlePan(_ gesture: UIPanGestureRecognizer){
34 | if viewControllers == nil || viewControllers?.count < 2 || containerTransitionDelegate == nil || !(containerTransitionDelegate is SDEContainerViewControllerDelegate) {
35 | return
36 | }
37 |
38 | let delegate = containerTransitionDelegate as! SDEContainerViewControllerDelegate
39 |
40 | let translationX = gesture.translation(in: view).x
41 | let translationAbs = translationX > 0 ? translationX : -translationX
42 | let progress = translationAbs / view.frame.width
43 | switch gesture.state{
44 | case .began:
45 | interactive = true
46 | let velocityX = gesture.velocity(in: view).x
47 | if velocityX < 0{
48 | if selectedIndex < viewControllers!.count - 1{
49 | selectedIndex += 1
50 | }
51 | }else{
52 | if selectedIndex > 0{
53 | selectedIndex -= 1
54 | }
55 | }
56 | case .changed:
57 | delegate.interactionController.updateInteractiveTransition(progress)
58 | case .cancelled, .ended:
59 | interactive = false
60 | if progress > 0.6{
61 | delegate.interactionController.finishInteractiveTransition()
62 | }else{
63 | delegate.interactionController.cancelInteractiveTransition()
64 | }
65 | default: break
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS-ViewController-Transition-Demo
2 | Update: 更新到了 Swift 3.0,意味着不再支持 iOS 7;依然在使用 Xcode 7 的用户可切换至 Swift 2.2 分支。
3 |
4 | [《iOS 视图控制器转场详解》](https://github.com/seedante/iOS-Note/wiki/ViewController-Transition)已发布到微信公众号「iOSDevTips」,这是配套 Demo,使用 Swift 实现。本文并非华丽的转场动画教程,相反,为了不让文章过于复杂和冗长,范例的转场动画效果都是入门级别的。为何弄这么简单的动画效果?转场动画=转场+动画,转场的部分与动画的部分是独立的,无论是简单的转场动画还是复杂的转场动画,他们在转场部分的复杂度几乎是一样的。文章着眼于探索视图控制器转场背后的机制,缺陷以及实现过程中的技巧与陷阱。
5 |
6 |
7 | ### 系统内建支持的转场
8 |
9 | 官方支持的四种转场:
10 |
11 | 1. UINavigationController 的 push 和 pop,Demo: NavigationControllerTransition,实现了交互控制。
12 | 2. UITabBarController 的 Tab 切换,Demo: ScrollTabBarController,实现了交互控制。
13 | 3. Modal 转场:presentation 和 dismissal,Demo: CustomModalTransition,当然也支持交互控制,但因为没有合适的交互手段,我在 Demo 里没有为这种转场实现交互控制。
14 | 4. UICollectionViewController 布局转场,Demo: CollectionViewControllerLayoutTransition,并非布局转换,而是 CollectionViewController 与 NavigationViewController 结合的转场,不支持交互控制。
15 |
16 |
17 | ### 自定义容器控制器转场
18 | 唯一算是有点技术含量的 Demo 是 CustomContainerVCTransition,系统并不支持自定义容器控制器的转场,这个话题其实在差不多2年前就有人讨论过, objc.io 在第12期动画专题里实现了[非交互控制的版本](https://www.objc.io/issues/12-animations/custom-container-view-controller-transitions/),并且把实现交互控制留给了读者,不过早已有读者完成了这道作业,依然是国外的开发者。如果你把 [WWDC 2013 Session 218:Custom Transitions Using View Controllers](https://developer.apple.com/videos/play/wwdc2013/218/) 和 [View Controller Programming Guide for iOS](https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/index.html#//apple_ref/doc/uid/TP40007457-CH2-SW1) 看个好几遍,自己再动手把主流的三种模式的转场动画都写一遍,即使是非常简单的动画,并且对协议有点感觉的话,到这个阶段基本上你该知道自定义容器控制器转场该怎么实现了,比较棘手的是交互控制,实际上 objc.io 在更早的 iOS 7专题里对这个话题有所涉及,objc.io 真是个宝库,不过另外一个关键的技术点在 Core Animation 文档里。objc.io 讨论这个话题时 Swift 还没发布,为了避免读者两头跑,我尝试了一个不同的动画效果从头探讨这个话题,如下:
19 |
20 | 
21 | 
22 |
23 | 熟能生巧,转场动画多写几次就知道了整个转场过程,你会发现转场其实蛮简单的,如果不考虑交互控制以及使用第三方的动画控制器,即使实现自定义容器控制器转场十几行代码就可以搞定,在文章里给出了具体代码。转场动画最困难的往往是动画效果本身,这取决于你对动画基础的掌握以及经验。
24 |
25 | ### iOS 10: 全程可交互的转场动画
26 | 上个月的 [WWDC 2016 Session 216: Advances in UIKit Animations and Transitions](https://developer.apple.com/videos/play/wwdc2016/216/) 介绍了全新的交互动画 API,并在 iOS 10 中将其引入了转场协议,之前的转场动画在非交互与交互状态之间有明显的界限:如果以交互转场开始,尽管在交互结束后会切换到非交互状态,但之后无法再次切换到交互状态,只能等待其结束;如果以非交互转场开始,在转场动画结束前是无法切换到交互控制状态的,只能等待其结束。新的交互动画 API 打破了这种界限,使得转场动画全程都可以在这两种状态之间自由切换。
27 |
28 | 不过,转场协议本身已略显臃肿,iOS 10在此基础上又添加了多个 optional,使得转场协议看上去复杂无比。我实践一番后,发现依靠新的交互动画 API,在实现转场动画可全程在非交互与交互之间自由切换的基础上,可以大幅精简转场协议。
29 |
30 | 这部分的内容在[《iOS 视图控制器转场详解》](https://github.com/seedante/iOS-Note/wiki/ViewController-Transition)更新,Demo: iOS10PushPop,需要使用 Xcode 8。
31 |
32 | 全新的交互动画 API 可以用于普通动画的交互。我在 [ControlPanelAnimation](https://github.com/seedante/ControlPanelAnimation) 里演示了如何使用 UIView Animation 和这个新交互动画 API 实现普通动画的交互。
33 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/CollectionVCTestTwo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionViewControllerTestTwo.swift
3 | // CollectionViewControllerLayoutTransition
4 | //
5 | // Created by seedante on 16/1/7.
6 | // Copyright © 2016年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /*
12 | 通过单例的数据源来测试布局转场在修改数据源下的表现,测试表明,这很不稳定,建议不要这么做。在 storyboard 将类切换到 CollectionVCTestTwo 便可以测试这种情况
13 | */
14 | class CollectionVCTestTwo: UICollectionViewController {
15 |
16 | var dataSource = CollectionViewDataSource.sharedInstance
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | self.collectionView?.dataSource = dataSource
21 | }
22 |
23 | override func didReceiveMemoryWarning() {
24 | super.didReceiveMemoryWarning()
25 | // Dispose of any resources that can be recreated.
26 | }
27 |
28 | override func viewDidAppear(_ animated: Bool) {
29 | super.viewDidAppear(animated)
30 | let count = self.navigationController!.viewControllers.count
31 | self.title = "Level \(count)"
32 | }
33 |
34 | //根据点击 cell 的位置来决定下一级的 CollectionView 的布局
35 | override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
36 | let layout = UICollectionViewFlowLayout()
37 | layout.itemSize = CGSize(width: indexPath.item * 10, height: indexPath.item * 10)
38 | layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10)
39 | //随机更改 cell 的数量
40 | dataSource.cellCount = Int(UInt32(arc4random()) % UInt32(10)) + 5
41 | let nextCVC = CollectionVCTestTwo(collectionViewLayout: layout)
42 | nextCVC.useLayoutToLayoutNavigationTransitions = true
43 | navigationController?.pushViewController(nextCVC, animated: true)
44 | }
45 | }
46 |
47 | class CollectionViewDataSource:NSObject, UICollectionViewDataSource {
48 |
49 | let reuseIdentifier = "Cell"
50 | static let sharedInstance = CollectionViewDataSource()
51 |
52 | var sectionCount = 2
53 | var cellCount = 15
54 |
55 | private override init() {}
56 |
57 | func numberOfSections(in collectionView: UICollectionView) -> Int {
58 | return sectionCount
59 | }
60 |
61 |
62 | @objc func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
63 | return cellCount
64 | }
65 |
66 | @available(iOS 6.0, *)
67 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
68 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath)
69 | if indexPath.section == 0{
70 | cell.backgroundColor = UIColor.red
71 | }else{
72 | cell.backgroundColor = UIColor.brown
73 | }
74 |
75 | return cell
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/SDENavigationDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SDENavigationDelegate.swift
3 | // iOS10PushPop
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIViewAnimatingPosition{
12 | var description: String{
13 | switch self {
14 | case .end:
15 | return "end"
16 | case .current:
17 | return "current"
18 | case .start:
19 | return "start"
20 | }
21 | }
22 | }
23 |
24 | @available(iOS 10.0, *)
25 | class SDENavigationDelegate: NSObject, UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning {
26 |
27 | var operation: UINavigationControllerOperation = .push
28 | let duration: TimeInterval = 1
29 |
30 | // MARK: UINavigationControllerDelegate
31 | func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
32 | self.operation = operation
33 | return self
34 | }
35 |
36 | // MARK: UIViewControllerAnimatedTransitioning
37 | /// If you change any of 'duration', keep two 'duration' same.
38 | var transitionAnimator: UIViewPropertyAnimator = UIViewPropertyAnimator(duration: 1, timingParameters: UISpringTimingParameters(dampingRatio: 1, initialVelocity: CGVector(dx: 1, dy: 0)))
39 |
40 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
41 | return duration
42 | }
43 |
44 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning){
45 | let containerView = transitionContext.containerView
46 | guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from),
47 | let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)
48 | else {
49 | return
50 | }
51 |
52 | var translation = containerView.frame.width
53 | translation = operation == .push ? translation : -translation
54 | containerView.addSubview(toView)
55 | toView.center.x += translation
56 |
57 | transitionAnimator.addAnimations({
58 | fromView.center.x -= translation
59 | toView.center.x -= translation
60 | })
61 |
62 | transitionAnimator.addCompletion({ position in
63 | fromView.center.x = containerView.center.x
64 | toView.center.x = containerView.center.x
65 |
66 | let completed = position == .end ? true : false
67 | transitionContext.completeTransition(completed)
68 | print("TransitionAnimation complete at position: \(position.description)")
69 | })
70 | transitionAnimator.startAnimation()
71 | print("Transition did start")
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/ScrollTabBarController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollTabBarController.swift
3 | // ScrollTabBarController
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ScrollTabBarController: UITabBarController {
12 |
13 | private var panGesture: UIPanGestureRecognizer = UIPanGestureRecognizer()
14 | private let tabBarVCDelegate = SDETabBarVCDelegate()
15 | private var subViewControllerCount: Int{
16 | let count = viewControllers != nil ? viewControllers!.count : 0
17 | return count
18 | }
19 |
20 | override func viewDidLoad() {
21 | super.viewDidLoad()
22 | delegate = tabBarVCDelegate
23 | self.tabBar.tintColor = UIColor.green
24 |
25 | panGesture.addTarget(self, action: #selector(ScrollTabBarController.handlePan(panGesture:)))
26 | view.addGestureRecognizer(panGesture)
27 | }
28 |
29 | override func didReceiveMemoryWarning() {
30 | super.didReceiveMemoryWarning()
31 | // Dispose of any resources that can be recreated.
32 | }
33 |
34 | func handlePan(panGesture: UIPanGestureRecognizer){
35 | let translationX = panGesture.translation(in: view).x
36 | let translationAbs = translationX > 0 ? translationX : -translationX
37 | let progress = translationAbs / view.frame.width
38 | switch panGesture.state{
39 | case .began:
40 | tabBarVCDelegate.interactive = true
41 | let velocityX = panGesture.velocity(in: view).x
42 | if velocityX < 0{
43 | if selectedIndex < subViewControllerCount - 1{
44 | selectedIndex += 1
45 | }
46 | }else {
47 | if selectedIndex > 0{
48 | selectedIndex -= 1
49 | }
50 | }
51 | case .changed:
52 | tabBarVCDelegate.interactionController.update(progress)
53 | case .cancelled, .ended:
54 | /*这里有个小问题,转场结束或是取消时有很大几率出现动画不正常的问题。在8.1以上版本的模拟器中都有发现,7.x 由于缺乏条件尚未测试,
55 | 但在我的 iOS 9.2 的真机设备上没有发现,而且似乎只在 UITabBarController 的交互转场中发现了这个问题。在 NavigationController 暂且没发现这个问题,
56 | Modal 转场尚未测试,因为我在 Demo 里没给它添加交互控制功能。
57 |
58 | 测试不完整,具体原因也未知,不过解决手段找到了。多谢 @llwenDeng 发现这个 Bug 并且找到了解决手段。
59 | 解决手段是修改交互控制器的 completionSpeed 为1以下的数值,这个属性用来控制动画速度,我猜测是内部实现在边界判断上有问题。
60 | 这里其修改为0.99,既解决了 Bug 同时尽可能贴近原来的动画设定。
61 | */
62 | if progress > 0.3{
63 | tabBarVCDelegate.interactionController.completionSpeed = 0.99
64 | tabBarVCDelegate.interactionController.finish()
65 | }else{
66 | //转场取消后,UITabBarController 自动恢复了 selectedIndex 的值,不需要我们手动恢复。
67 | tabBarVCDelegate.interactionController.completionSpeed = 0.99
68 | tabBarVCDelegate.interactionController.cancel()
69 | }
70 | tabBarVCDelegate.interactive = false
71 | default: break
72 | }
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/OverlayAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OverlayAnimationController.swift
3 | // CustomPresentationTransition
4 | //
5 | // Created by seedante on 15/12/20.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class OverlayAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
12 |
13 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
14 | return 0.3
15 | }
16 |
17 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
18 | let containerView = transitionContext.containerView
19 | guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
20 | return
21 | }
22 |
23 | let fromView = fromVC.view
24 | let toView = toVC.view
25 | let duration = self.transitionDuration(using: transitionContext)
26 |
27 | if toVC.isBeingPresented{
28 | containerView.addSubview(toView!)
29 | let toViewWidth = containerView.frame.width * 2 / 3, toViewHeight = containerView.frame.height * 2 / 3
30 | toView?.center = containerView.center
31 | toView?.bounds = CGRect(x: 0, y: 0, width: 1, height: toViewHeight)
32 |
33 | if #available(iOS 8, *){
34 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseInOut, animations: {
35 | toView?.bounds = CGRect(x: 0, y: 0, width: toViewWidth, height: toViewHeight)
36 | }, completion: {_ in
37 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
38 | })
39 | }else{
40 | // 文章里的示范代码是基于 iOS 7 以上的系统的,但是升级到 Swift 3.0 后,这段代码就没用了,仅对应文章里的旧代码。
41 | // 这段代码给 toView 添加了一个半透明的背景,在 iOS 8 中,这个背景由 OverlayPresentationController.swift 去添加。
42 | let dimmingView = UIView()
43 | containerView.insertSubview(dimmingView, belowSubview: toView!)
44 | dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
45 | dimmingView.center = containerView.center
46 | dimmingView.bounds = CGRect(x: 0, y: 0, width: toViewWidth, height: toViewHeight)
47 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
48 | dimmingView.bounds = containerView.bounds
49 | toView?.bounds = CGRect(x: 0, y: 0, width: toViewWidth, height: toViewHeight)
50 | }, completion: { _ in
51 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
52 | })
53 |
54 | }
55 | }
56 | //Dismissal 转场中不要将 toView 添加到 containerView
57 | if fromVC.isBeingDismissed{
58 | let fromViewHeight = fromView?.frame.height
59 | UIView.animate(withDuration: duration, animations: {
60 | fromView?.bounds = CGRect(x: 0, y: 0, width: 1, height: fromViewHeight!)
61 | }, completion: { _ in
62 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
63 | })
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/iOS10PushPop/iOS10PushPop.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/iOS10PushPop.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/ScrollTabBarController.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/CustomModalTransition.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/CustomContainerVCTransition.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/NavigationControllerTransitionDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition.xcodeproj/xcuserdata/seedante.xcuserdatad/xcschemes/CollectionVCLayoutTransition.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/InterruptibleNavigationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterruptibleNavigationController.swift
3 | // iOS10PushPop
4 | //
5 | // Created by seedante on 16/6/28.
6 | // Copyright © 2016年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | @available(iOS 10.0, *)
13 | class InterruptibleNavigationController: UINavigationController
14 | {
15 |
16 | var pan = UIPanGestureRecognizer()
17 | var tap = UITapGestureRecognizer()
18 | var navigationDelegate: SDENavigationDelegate = SDENavigationDelegate()
19 | var fractionComplete: CGFloat = 0
20 |
21 | override func viewDidLoad() {
22 | super.viewDidLoad()
23 |
24 | // Do any additional setup after loading the view.
25 | pan.addTarget(self, action: #selector(InterruptibleNavigationController.handlePan(gesture:)))
26 | tap.addTarget(self, action: #selector(InterruptibleNavigationController.handleTap(gesture:)))
27 | view.addGestureRecognizer(pan)
28 | view.addGestureRecognizer(tap)
29 |
30 | delegate = navigationDelegate
31 | }
32 |
33 | func handleTap(gesture: UITapGestureRecognizer){
34 | let animator = navigationDelegate.transitionAnimator
35 |
36 | switch gesture.state {
37 | case .ended, .cancelled:
38 | switch animator.state {
39 | case .active:
40 | animator.pauseAnimation()
41 | animator.isReversed = !(animator.isReversed)
42 | animator.startAnimation()
43 | default:break
44 | }
45 | default:break
46 | }
47 | }
48 |
49 |
50 | func handlePan(gesture: UIPanGestureRecognizer){
51 | let animator = navigationDelegate.transitionAnimator
52 |
53 | let translationX = gesture.translation(in: view).x
54 | let operation: UINavigationControllerOperation = translationX > 0 ? .pop : .push
55 | let translationBase: CGFloat = view.frame.width
56 | let translationAbs = translationX > 0 ? translationX : -translationX
57 | let percent = translationAbs > translationBase ? 1.0 : translationX / translationBase
58 |
59 | switch gesture.state{
60 | case .began:
61 | if animator.isRunning == false{
62 | switch operation {
63 | case .pop:
64 | if viewControllers.count == 2{
65 | popViewController(animated: true)
66 | }
67 | case .push:
68 | if viewControllers.count == 1{
69 | let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "BlueVC")
70 | pushViewController(nextVC!, animated: true)
71 | }
72 | default:break
73 | }
74 | }else{
75 | animator.pauseAnimation()
76 | fractionComplete = animator.fractionComplete
77 | }
78 | case .changed:
79 | if animator.isRunning{
80 | animator.pauseAnimation()
81 | fractionComplete = animator.fractionComplete
82 | }else if animator.state == .active{
83 | if operation == navigationDelegate.operation{
84 | animator.fractionComplete = abs(percent) + fractionComplete
85 | }else{
86 | animator.fractionComplete = fractionComplete - abs(percent)
87 | }
88 | }
89 | case .cancelled, .ended:
90 | if animator.state == .active{
91 | if animator.fractionComplete < 0.3{
92 | animator.isReversed = true
93 | }
94 | let velocityX = abs(gesture.velocity(in: view).x) / (view.frame.width * (1 - animator.fractionComplete))
95 | let initialVelocity = CGVector(dx: velocityX, dy: 0)
96 | animator.continueAnimation(withTimingParameters: UISpringTimingParameters(dampingRatio: 0.9, initialVelocity: initialVelocity), durationFactor: 0)
97 | }
98 | default: break
99 | }
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController.xcodeproj/xcuserdata/seedante.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
40 |
52 |
53 |
67 |
68 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/CollectionViewControllerLayoutTransition/CollectionViewControllerLayoutTransition/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/iOS10PushPop/InterruptibleTransition/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/SlideAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PushAndPopAnimationController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum SDETransitionType{
12 | case navigationTransition(UINavigationControllerOperation)
13 | case tabTransition(TabOperationDirection)
14 | case modalTransition(ModalOperation)
15 | }
16 |
17 | enum TabOperationDirection{
18 | case left, right
19 | }
20 |
21 | enum ModalOperation{
22 | case presentation, dismissal
23 | }
24 |
25 | class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
26 |
27 | private var transitionType: SDETransitionType
28 |
29 | init(type: SDETransitionType) {
30 | transitionType = type
31 | super.init()
32 | }
33 |
34 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
35 | return 0.3
36 | }
37 |
38 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
39 | let containerView = transitionContext.containerView
40 | guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
41 | return
42 | }
43 |
44 | let fromView = fromVC.view
45 | let toView = toVC.view
46 |
47 | var translation = containerView.frame.width
48 | var toViewTransform = CGAffineTransform.identity
49 | var fromViewTransform = CGAffineTransform.identity
50 |
51 | switch transitionType{
52 | case .navigationTransition(let operation):
53 | translation = operation == .push ? translation : -translation
54 | toViewTransform = CGAffineTransform(translationX: translation, y: 0)
55 | fromViewTransform = CGAffineTransform(translationX: -translation, y: 0)
56 | case .tabTransition(let direction):
57 | translation = direction == .left ? translation : -translation
58 | fromViewTransform = CGAffineTransform(translationX: translation, y: 0)
59 | toViewTransform = CGAffineTransform(translationX: -translation, y: 0)
60 | case .modalTransition(let operation):
61 | translation = containerView.frame.height
62 | toViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? translation : 0))
63 | fromViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? 0 : translation))
64 | }
65 |
66 | switch transitionType{
67 | case .modalTransition(let operation):
68 | switch operation{
69 | case .presentation: containerView.addSubview(toView!)
70 | case .dismissal: break
71 | }
72 | default: containerView.addSubview(toView!)
73 | }
74 |
75 | toView?.transform = toViewTransform
76 | UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
77 | fromView?.transform = fromViewTransform
78 | toView?.transform = CGAffineTransform.identity
79 | }, completion: { finished in
80 | fromView?.transform = CGAffineTransform.identity
81 | toView?.transform = CGAffineTransform.identity
82 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
83 | })
84 | }
85 |
86 | /*
87 | 下面这段被注释的代码是使用 Core Animation 来实现转场,在非交互转场时没有问题,在交互转场下会有点瑕疵,要达到完美要麻烦一点。
88 |
89 | 交互转场必须用 UIView Animtion API 才能实现完美的控制,其实并不是 Core Animation 做不到,
90 | 毕竟 UIView Animation 是基于 Core Animation 的,那为什么苹果的工程师在 WWDC 上说必须使用前者呢。
91 | 因为使用 Core Animation 来实现成本高啊,在转场中做到与 UIView Animation 同样的事情配置麻烦些,估计很多人都不会配置,
92 | 而且在交互转场中会比较麻烦,本来转场 API 已经分裂得够复杂了,老老实实用高级 API 吧。
93 |
94 | 上面说的 UIView Animation API 指的是带 completion 闭包的 API,使用 Core Animation 来实现这个闭包需要配置
95 | CATransaction,这就是麻烦的地方,还是用高级的 API 吧。
96 |
97 | 在自定义的容器控制器转场中,交互部分需要我们自己动手实现控制动画的进度,此时 使用 Core Animation 或 UIView Animation
98 | 区别不大,重点在于在手势中如何控制动画。
99 | */
100 |
101 | // func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
102 | // let containerView = transitionContext.containerView
103 | // guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
104 | // return
105 | // }
106 | //
107 | //
108 | // let fromView = fromVC.view
109 | // let toView = toVC.view
110 | //
111 | // var translation = containerView.frame.width
112 | // var toViewTransform = CATransform3DIdentity
113 | // var fromViewTransform = CATransform3DIdentity
114 | //
115 | // switch transitionType{
116 | // case .navigationTransition(let operation):
117 | // translation = operation == .push ? translation : -translation
118 | // toViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
119 | // fromViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
120 | // case .tabTransition(let direction):
121 | // translation = direction == .left ? translation : -translation
122 | // fromViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
123 | // toViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
124 | // case .modalTransition(let operation):
125 | // translation = containerView.frame.height
126 | // toViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? translation : 0), 0)
127 | // fromViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? 0 : translation), 0)
128 | // }
129 | //
130 | // switch transitionType{
131 | // case .modalTransition(let operation):
132 | // switch operation{
133 | // case .presentation: containerView.addSubview(toView!)
134 | // //在 dismissal 转场中,不要添加 toView,否则黑屏
135 | // case .dismissal: break
136 | // }
137 | // default: containerView.addSubview(toView!)
138 | // }
139 | //
140 | // let duration = transitionDuration(using: transitionContext)
141 | // CATransaction.setCompletionBlock({
142 | // fromView?.layer.transform = CATransform3DIdentity
143 | // toView?.layer.transform = CATransform3DIdentity
144 | // transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
145 | // })
146 | //
147 | // CATransaction.setAnimationDuration(duration)
148 | // CATransaction.begin()
149 | //
150 | // let toViewAnimation = CABasicAnimation(keyPath: "transform")
151 | // toViewAnimation.fromValue = NSValue.init(caTransform3D: toViewTransform)
152 | // toViewAnimation.toValue = NSValue.init(caTransform3D: CATransform3DIdentity)
153 | // toViewAnimation.duration = duration
154 | // toView?.layer.add(toViewAnimation, forKey: "move")
155 | //
156 | // let fromViewAnimation = CABasicAnimation(keyPath: "transform")
157 | // fromViewAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DIdentity)
158 | // fromViewAnimation.toValue = NSValue.init(caTransform3D: fromViewTransform)
159 | // fromViewAnimation.duration = duration
160 | // fromView?.layer.add(fromViewAnimation, forKey: "move")
161 | //
162 | // CATransaction.commit()
163 | // }
164 |
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/ScrollTabBarController/ScrollTabBarController/SlideAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PushAndPopAnimationController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum SDETransitionType{
12 | case navigationTransition(UINavigationControllerOperation)
13 | case tabTransition(TabOperationDirection)
14 | case modalTransition(ModalOperation)
15 | }
16 |
17 | enum TabOperationDirection{
18 | case left, right
19 | }
20 |
21 | enum ModalOperation{
22 | case presentation, dismissal
23 | }
24 |
25 | class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
26 |
27 | private var transitionType: SDETransitionType
28 |
29 | init(type: SDETransitionType) {
30 | transitionType = type
31 | super.init()
32 | }
33 |
34 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
35 | return 0.3
36 | }
37 |
38 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
39 | let containerView = transitionContext.containerView
40 | guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
41 | return
42 | }
43 |
44 | let fromView = fromVC.view
45 | let toView = toVC.view
46 |
47 | var translation = containerView.frame.width
48 | var toViewTransform = CGAffineTransform.identity
49 | var fromViewTransform = CGAffineTransform.identity
50 |
51 | switch transitionType{
52 | case .navigationTransition(let operation):
53 | translation = operation == .push ? translation : -translation
54 | toViewTransform = CGAffineTransform(translationX: translation, y: 0)
55 | fromViewTransform = CGAffineTransform(translationX: -translation, y: 0)
56 | case .tabTransition(let direction):
57 | translation = direction == .left ? translation : -translation
58 | fromViewTransform = CGAffineTransform(translationX: translation, y: 0)
59 | toViewTransform = CGAffineTransform(translationX: -translation, y: 0)
60 | case .modalTransition(let operation):
61 | translation = containerView.frame.height
62 | toViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? translation : 0))
63 | fromViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? 0 : translation))
64 | }
65 |
66 | switch transitionType{
67 | case .modalTransition(let operation):
68 | switch operation{
69 | case .presentation: containerView.addSubview(toView!)
70 | case .dismissal: break
71 | }
72 | default: containerView.addSubview(toView!)
73 | }
74 |
75 | toView?.transform = toViewTransform
76 | UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
77 | fromView?.transform = fromViewTransform
78 | toView?.transform = CGAffineTransform.identity
79 | }, completion: { finished in
80 | fromView?.transform = CGAffineTransform.identity
81 | toView?.transform = CGAffineTransform.identity
82 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
83 | })
84 | }
85 |
86 | /*
87 | 下面这段被注释的代码是使用 Core Animation 来实现转场,在非交互转场时没有问题,在交互转场下会有点瑕疵,要达到完美要麻烦一点。
88 |
89 | 交互转场必须用 UIView Animtion API 才能实现完美的控制,其实并不是 Core Animation 做不到,
90 | 毕竟 UIView Animation 是基于 Core Animation 的,那为什么苹果的工程师在 WWDC 上说必须使用前者呢。
91 | 因为使用 Core Animation 来实现成本高啊,在转场中做到与 UIView Animation 同样的事情配置麻烦些,估计很多人都不会配置,
92 | 而且在交互转场中会比较麻烦,本来转场 API 已经分裂得够复杂了,老老实实用高级 API 吧。
93 |
94 | 上面说的 UIView Animation API 指的是带 completion 闭包的 API,使用 Core Animation 来实现这个闭包需要配置
95 | CATransaction,这就是麻烦的地方,还是用高级的 API 吧。
96 |
97 | 在自定义的容器控制器转场中,交互部分需要我们自己动手实现控制动画的进度,此时 使用 Core Animation 或 UIView Animation
98 | 区别不大,重点在于在手势中如何控制动画。
99 | */
100 |
101 | // func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
102 | // let containerView = transitionContext.containerView
103 | // guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
104 | // return
105 | // }
106 | //
107 | //
108 | // let fromView = fromVC.view
109 | // let toView = toVC.view
110 | //
111 | // var translation = containerView.frame.width
112 | // var toViewTransform = CATransform3DIdentity
113 | // var fromViewTransform = CATransform3DIdentity
114 | //
115 | // switch transitionType{
116 | // case .navigationTransition(let operation):
117 | // translation = operation == .push ? translation : -translation
118 | // toViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
119 | // fromViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
120 | // case .tabTransition(let direction):
121 | // translation = direction == .left ? translation : -translation
122 | // fromViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
123 | // toViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
124 | // case .modalTransition(let operation):
125 | // translation = containerView.frame.height
126 | // toViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? translation : 0), 0)
127 | // fromViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? 0 : translation), 0)
128 | // }
129 | //
130 | // switch transitionType{
131 | // case .modalTransition(let operation):
132 | // switch operation{
133 | // case .presentation: containerView.addSubview(toView!)
134 | // //在 dismissal 转场中,不要添加 toView,否则黑屏
135 | // case .dismissal: break
136 | // }
137 | // default: containerView.addSubview(toView!)
138 | // }
139 | //
140 | // let duration = transitionDuration(using: transitionContext)
141 | // CATransaction.setCompletionBlock({
142 | // fromView?.layer.transform = CATransform3DIdentity
143 | // toView?.layer.transform = CATransform3DIdentity
144 | // transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
145 | // })
146 | //
147 | // CATransaction.setAnimationDuration(duration)
148 | // CATransaction.begin()
149 | //
150 | // let toViewAnimation = CABasicAnimation(keyPath: "transform")
151 | // toViewAnimation.fromValue = NSValue.init(caTransform3D: toViewTransform)
152 | // toViewAnimation.toValue = NSValue.init(caTransform3D: CATransform3DIdentity)
153 | // toViewAnimation.duration = duration
154 | // toView?.layer.add(toViewAnimation, forKey: "move")
155 | //
156 | // let fromViewAnimation = CABasicAnimation(keyPath: "transform")
157 | // fromViewAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DIdentity)
158 | // fromViewAnimation.toValue = NSValue.init(caTransform3D: fromViewTransform)
159 | // fromViewAnimation.duration = duration
160 | // fromView?.layer.add(fromViewAnimation, forKey: "move")
161 | //
162 | // CATransaction.commit()
163 | // }
164 |
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/CustomContainerVCTransition/CustomContainerVCTransition/SlideAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PushAndPopAnimationController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum SDETransitionType{
12 | case navigationTransition(UINavigationControllerOperation)
13 | case tabTransition(TabOperationDirection)
14 | case modalTransition(ModalOperation)
15 | }
16 |
17 | enum TabOperationDirection{
18 | case left, right
19 | }
20 |
21 | enum ModalOperation{
22 | case presentation, dismissal
23 | }
24 |
25 | class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
26 |
27 | fileprivate var transitionType: SDETransitionType
28 |
29 | init(type: SDETransitionType) {
30 | transitionType = type
31 | super.init()
32 | }
33 |
34 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
35 | return 0.3
36 | }
37 |
38 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
39 | let containerView = transitionContext.containerView
40 | guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
41 | return
42 | }
43 |
44 | let fromView = fromVC.view
45 | let toView = toVC.view
46 |
47 | var translation = containerView.frame.width
48 | var toViewTransform = CGAffineTransform.identity
49 | var fromViewTransform = CGAffineTransform.identity
50 |
51 | switch transitionType{
52 | case .navigationTransition(let operation):
53 | translation = operation == .push ? translation : -translation
54 | toViewTransform = CGAffineTransform(translationX: translation, y: 0)
55 | fromViewTransform = CGAffineTransform(translationX: -translation, y: 0)
56 | case .tabTransition(let direction):
57 | translation = direction == .left ? translation : -translation
58 | fromViewTransform = CGAffineTransform(translationX: translation, y: 0)
59 | toViewTransform = CGAffineTransform(translationX: -translation, y: 0)
60 | case .modalTransition(let operation):
61 | translation = containerView.frame.height
62 | toViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? translation : 0))
63 | fromViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? 0 : translation))
64 | }
65 |
66 | switch transitionType{
67 | case .modalTransition(let operation):
68 | switch operation{
69 | case .presentation: containerView.addSubview(toView!)
70 | case .dismissal: break
71 | }
72 | default: containerView.addSubview(toView!)
73 | }
74 |
75 | toView?.transform = toViewTransform
76 | UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
77 | fromView?.transform = fromViewTransform
78 | toView?.transform = CGAffineTransform.identity
79 | }, completion: { finished in
80 | fromView?.transform = CGAffineTransform.identity
81 | toView?.transform = CGAffineTransform.identity
82 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
83 | })
84 | }
85 |
86 | /*
87 | 下面这段被注释的代码是使用 Core Animation 来实现转场,在非交互转场时没有问题,在交互转场下会有点瑕疵,要达到完美要麻烦一点。
88 |
89 | 交互转场必须用 UIView Animtion API 才能实现完美的控制,其实并不是 Core Animation 做不到,
90 | 毕竟 UIView Animation 是基于 Core Animation 的,那为什么苹果的工程师在 WWDC 上说必须使用前者呢。
91 | 因为使用 Core Animation 来实现成本高啊,在转场中做到与 UIView Animation 同样的事情配置麻烦些,估计很多人都不会配置,
92 | 而且在交互转场中会比较麻烦,本来转场 API 已经分裂得够复杂了,老老实实用高级 API 吧。
93 |
94 | 上面说的 UIView Animation API 指的是带 completion 闭包的 API,使用 Core Animation 来实现这个闭包需要配置
95 | CATransaction,这就是麻烦的地方,还是用高级的 API 吧。
96 |
97 | 在自定义的容器控制器转场中,交互部分需要我们自己动手实现控制动画的进度,此时 使用 Core Animation 或 UIView Animation
98 | 区别不大,重点在于在手势中如何控制动画。
99 | */
100 |
101 | // func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
102 | // let containerView = transitionContext.containerView
103 | // guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
104 | // return
105 | // }
106 | //
107 | //
108 | // let fromView = fromVC.view
109 | // let toView = toVC.view
110 | //
111 | // var translation = containerView.frame.width
112 | // var toViewTransform = CATransform3DIdentity
113 | // var fromViewTransform = CATransform3DIdentity
114 | //
115 | // switch transitionType{
116 | // case .navigationTransition(let operation):
117 | // translation = operation == .push ? translation : -translation
118 | // toViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
119 | // fromViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
120 | // case .tabTransition(let direction):
121 | // translation = direction == .left ? translation : -translation
122 | // fromViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
123 | // toViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
124 | // case .modalTransition(let operation):
125 | // translation = containerView.frame.height
126 | // toViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? translation : 0), 0)
127 | // fromViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? 0 : translation), 0)
128 | // }
129 | //
130 | // switch transitionType{
131 | // case .modalTransition(let operation):
132 | // switch operation{
133 | // case .presentation: containerView.addSubview(toView!)
134 | // //在 dismissal 转场中,不要添加 toView,否则黑屏
135 | // case .dismissal: break
136 | // }
137 | // default: containerView.addSubview(toView!)
138 | // }
139 | //
140 | // let duration = transitionDuration(using: transitionContext)
141 | // CATransaction.setCompletionBlock({
142 | // fromView?.layer.transform = CATransform3DIdentity
143 | // toView?.layer.transform = CATransform3DIdentity
144 | // transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
145 | // })
146 | //
147 | // CATransaction.setAnimationDuration(duration)
148 | // CATransaction.begin()
149 | //
150 | // let toViewAnimation = CABasicAnimation(keyPath: "transform")
151 | // toViewAnimation.fromValue = NSValue.init(caTransform3D: toViewTransform)
152 | // toViewAnimation.toValue = NSValue.init(caTransform3D: CATransform3DIdentity)
153 | // toViewAnimation.duration = duration
154 | // toView?.layer.add(toViewAnimation, forKey: "move")
155 | //
156 | // let fromViewAnimation = CABasicAnimation(keyPath: "transform")
157 | // fromViewAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DIdentity)
158 | // fromViewAnimation.toValue = NSValue.init(caTransform3D: fromViewTransform)
159 | // fromViewAnimation.duration = duration
160 | // fromView?.layer.add(fromViewAnimation, forKey: "move")
161 | //
162 | // CATransaction.commit()
163 | // }
164 |
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/NavigationControllerTransition/NavigationControllerTransitionDemo/SlideAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PushAndPopAnimationController.swift
3 | // NavigationControllerTransitionDemo
4 | //
5 | // Created by seedante on 15/12/9.
6 | // Copyright © 2015年 seedante. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum SDETransitionType{
12 | case navigationTransition(UINavigationControllerOperation)
13 | case tabTransition(TabOperationDirection)
14 | case modalTransition(ModalOperation)
15 | }
16 |
17 | enum TabOperationDirection{
18 | case left, right
19 | }
20 |
21 | enum ModalOperation{
22 | case presentation, dismissal
23 | }
24 |
25 | class SlideAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
26 |
27 | private var transitionType: SDETransitionType
28 |
29 | init(type: SDETransitionType) {
30 | transitionType = type
31 | super.init()
32 | }
33 |
34 | func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
35 | return 0.3
36 | }
37 |
38 | func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
39 | let containerView = transitionContext.containerView
40 | guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
41 | return
42 | }
43 |
44 | let fromView = fromVC.view
45 | let toView = toVC.view
46 |
47 | var translation = containerView.frame.width
48 | var toViewTransform = CGAffineTransform.identity
49 | var fromViewTransform = CGAffineTransform.identity
50 |
51 | switch transitionType{
52 | case .navigationTransition(let operation):
53 | translation = operation == .push ? translation : -translation
54 | toViewTransform = CGAffineTransform(translationX: translation, y: 0)
55 | fromViewTransform = CGAffineTransform(translationX: -translation, y: 0)
56 | case .tabTransition(let direction):
57 | translation = direction == .left ? translation : -translation
58 | fromViewTransform = CGAffineTransform(translationX: translation, y: 0)
59 | toViewTransform = CGAffineTransform(translationX: -translation, y: 0)
60 | case .modalTransition(let operation):
61 | translation = containerView.frame.height
62 | toViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? translation : 0))
63 | fromViewTransform = CGAffineTransform(translationX: 0, y: (operation == .presentation ? 0 : translation))
64 | }
65 |
66 | switch transitionType{
67 | case .modalTransition(let operation):
68 | switch operation{
69 | case .presentation: containerView.addSubview(toView!)
70 | case .dismissal: break
71 | }
72 | default: containerView.addSubview(toView!)
73 | }
74 |
75 | toView?.transform = toViewTransform
76 | UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
77 | fromView?.transform = fromViewTransform
78 | toView?.transform = CGAffineTransform.identity
79 | }, completion: { finished in
80 | fromView?.transform = CGAffineTransform.identity
81 | toView?.transform = CGAffineTransform.identity
82 | transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
83 | })
84 | }
85 |
86 | /*
87 | 下面这段被注释的代码是使用 Core Animation 来实现转场,在非交互转场时没有问题,在交互转场下会有点瑕疵,要达到完美要麻烦一点。
88 |
89 | 交互转场必须用 UIView Animtion API 才能实现完美的控制,其实并不是 Core Animation 做不到,
90 | 毕竟 UIView Animation 是基于 Core Animation 的,那为什么苹果的工程师在 WWDC 上说必须使用前者呢。
91 | 因为使用 Core Animation 来实现成本高啊,在转场中做到与 UIView Animation 同样的事情配置麻烦些,估计很多人都不会配置,
92 | 而且在交互转场中会比较麻烦,本来转场 API 已经分裂得够复杂了,老老实实用高级 API 吧。
93 |
94 | 上面说的 UIView Animation API 指的是带 completion 闭包的 API,使用 Core Animation 来实现这个闭包需要配置
95 | CATransaction,这就是麻烦的地方,还是用高级的 API 吧。
96 |
97 | 在自定义的容器控制器转场中,交互部分需要我们自己动手实现控制动画的进度,此时 使用 Core Animation 或 UIView Animation
98 | 区别不大,重点在于在手势中如何控制动画。
99 | */
100 |
101 | // func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
102 | // let containerView = transitionContext.containerView
103 | // guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else{
104 | // return
105 | // }
106 | //
107 | //
108 | // let fromView = fromVC.view
109 | // let toView = toVC.view
110 | //
111 | // var translation = containerView.frame.width
112 | // var toViewTransform = CATransform3DIdentity
113 | // var fromViewTransform = CATransform3DIdentity
114 | //
115 | // switch transitionType{
116 | // case .navigationTransition(let operation):
117 | // translation = operation == .push ? translation : -translation
118 | // toViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
119 | // fromViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
120 | // case .tabTransition(let direction):
121 | // translation = direction == .left ? translation : -translation
122 | // fromViewTransform = CATransform3DMakeTranslation(translation, 0, 0)
123 | // toViewTransform = CATransform3DMakeTranslation(-translation, 0, 0)
124 | // case .modalTransition(let operation):
125 | // translation = containerView.frame.height
126 | // toViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? translation : 0), 0)
127 | // fromViewTransform = CATransform3DMakeTranslation(0, (operation == .presentation ? 0 : translation), 0)
128 | // }
129 | //
130 | // switch transitionType{
131 | // case .modalTransition(let operation):
132 | // switch operation{
133 | // case .presentation: containerView.addSubview(toView!)
134 | // //在 dismissal 转场中,不要添加 toView,否则黑屏
135 | // case .dismissal: break
136 | // }
137 | // default: containerView.addSubview(toView!)
138 | // }
139 | //
140 | // let duration = transitionDuration(using: transitionContext)
141 | // CATransaction.setCompletionBlock({
142 | // fromView?.layer.transform = CATransform3DIdentity
143 | // toView?.layer.transform = CATransform3DIdentity
144 | // transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
145 | // })
146 | //
147 | // CATransaction.setAnimationDuration(duration)
148 | // CATransaction.begin()
149 | //
150 | // let toViewAnimation = CABasicAnimation(keyPath: "transform")
151 | // toViewAnimation.fromValue = NSValue.init(caTransform3D: toViewTransform)
152 | // toViewAnimation.toValue = NSValue.init(caTransform3D: CATransform3DIdentity)
153 | // toViewAnimation.duration = duration
154 | // toView?.layer.add(toViewAnimation, forKey: "move")
155 | //
156 | // let fromViewAnimation = CABasicAnimation(keyPath: "transform")
157 | // fromViewAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DIdentity)
158 | // fromViewAnimation.toValue = NSValue.init(caTransform3D: fromViewTransform)
159 | // fromViewAnimation.duration = duration
160 | // fromView?.layer.add(fromViewAnimation, forKey: "move")
161 | //
162 | // CATransaction.commit()
163 | // }
164 |
165 | }
166 |
167 |
--------------------------------------------------------------------------------
/CustomModalTransition/CustomModalTransition/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------