рдирдорд╕реНрдХрд╛рд░, рд╣реЗрдмреНрд░! рд╣рд░ рдХреЛрдИ рдЙрддреНрддрд░рджрд╛рдпреА рдХреНрд╖реБрдзрд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реИред рдФрд░ рднреА рдмреЗрд╣рддрд░ рдЬрдм рдЙрдирдХреЗ рдкрд╛рд╕ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдПрдирд┐рдореЗрд╢рди рд╣реЛрдВред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рд╕рднреА "рдорд╛рдВрд╕" рдХреЗ рд╕рд╛рде рдмрддрд╛рдКрдВрдЧрд╛ рдФрд░ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдкреЙрдк-рдЕрдк рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдареАрдХ рд╕реЗ рджрд┐рдЦрд╛рдирд╛, рдЫрд┐рдкрд╛рдирд╛, рдореЛрдбрд╝рдирд╛, рдШреВрдордирд╛ рдФрд░ рдХрд░рдирд╛ рд╣реИред

рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВ рдпрд╣ рдХрд╣рддреЗ рд╣реБрдП рдПрдХ рд▓реЗрдЦ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ iOS 10 рдкрд░ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ UIViewPropertyAnimator
рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рдЬреЛ рдмрд╛рдзрд┐рдд рдПрдирд┐рдореЗрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИред рдЕрдм рдЙрдиреНрд╣реЗрдВ рд░реЛрдХрд╛, рдЙрд▓рдЯрд╛, рдЬрд╛рд░реА рдпрд╛ рд░рджреНрдж рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред Apple рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рджреНрд░рд╡ рдХрд╣рддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рддрдм рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ: рдЗрди рд╕рдВрдХреНрд░рдордгреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдПрдирд┐рдореЗрдЯреЗрдб рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдП рдмрд┐рдирд╛ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рдПрдиреАрдореЗрд╢рди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдЗрд╕рд▓рд┐рдП, рджреЛ рд▓реЗрдЦ рд╣реЛрдВрдЧреЗред рдЗрд╕рдореЗрдВ, рд╣рдо рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗ рдХрд┐ рд╕реНрдХреНрд░реАрди рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдирд╛ рдФрд░ рдЫрд┐рдкрд╛рдирд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓реЗ рдореЗрдВ рд░реБрдХрд╛рд╡рдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред
рд╡реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ?
UIViewController
рдореЗрдВ рдПрдХ UIViewController
рд╕рдВрдкрддреНрддрд┐ рд╣реИред рдпрд╣ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдПрдХ рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
animationController
рд▓рд┐рдП,interactionController
рдХрдВрдЯреНрд░реЛрд▓рд░ рдПрдирд┐рдореЗрд╢рди рдореЗрдВ рджрдЦрд▓ interactionController
рд▓рд┐рдП,presentationController
рдлреЙрд░ рдбрд┐рд╕реНрдкреНрд▓реЗ: рдкрджрд╛рдиреБрдХреНрд░рдо, рдлреНрд░реЗрдо рдЖрджрд┐ред

рдЗрди рд╕рднреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдПрдХ рдкреЙрдкрдЕрдк рдкреИрдирд▓ рдмрдирд╛рдПрдВрдЧреЗ:

рдкрд╛рдХ рдХрд▓рд╛ рдирд┐рдпрдВрддреНрд░рдХ
рдЖрдк рдореЛрдбрд▓ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдФрд░ UINavigationController
( UINavigationControllerDelegate
рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ) рдХреЗ рд▓рд┐рдП рд╕рдВрдХреНрд░рдордг рдХреЛ рдЪреЗрддрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо рдореЛрдбрд▓ рдЯреНрд░рд╛рдВрдЬрд╝рд┐рд╢рди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рд╢реЛ рд╕реЗ рдкрд╣рд▓реЗ рдирд┐рдпрдВрддреНрд░рдХ рд╕реЗрдЯрдЕрдк рдереЛрдбрд╝рд╛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИ:
class ParentViewController: UIViewController { private let transition = PanelTransition()
- рдПрдХ рд╡рд╕реНрддреБ рдмрдирд╛рдПрдВ рдЬреЛ рд╕рдВрдХреНрд░рдордг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИред
transitioningDelegate
рдХреЛ weak
рдХреЗ рд░реВрдк transitioningDelegate
рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ strong
рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ transition
рдЕрд▓рдЧ рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред - рд╣рдордиреЗ рдЕрдкрдирд╛ рдкрд░рд┐рд╡рд░реНрддрди рдЯреНрд░рд╛рдВрд╕реНрдлрд╝реЙрд░реНрдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд┐рдпрд╛ред
presentationController
.custom
рдореЗрдВ рдбрд┐рд╕реНрдкреНрд▓реЗ рд╡рд┐рдзрд┐ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ .custom
рд▓рд┐рдП modalPresentationStyle.
рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ modalPresentationStyle.
ред
рджрд┐рдЦрд╛рдП рдЧрдП рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рд╡рд╣ рдЕрдЪреНрдЫрд╛ рд╣реИред
рдЖрдзреА рд╕реНрдХреНрд░реАрди рдореЗрдВ рджрд┐рдЦрд╛
рдХреЗ PanelTransition
рдХреЛрдб рдХреЛ presentationController
рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдкрдиреЗ UIPopoverController
рдорд╛рдзреНрдпрдо рд╕реЗ рдкреЙрдк-рдЕрдк рдмрдирд╛рдпрд╛ рд╣реИ рддреЛ рдЖрдкрдиреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИред PresentationController
рдХрдВрдЯреНрд░реЛрд▓рд░ рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рдбрд┐рд╕реНрдкреНрд▓реЗ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ: рдлреНрд░реЗрдо, рдкрджрд╛рдиреБрдХреНрд░рдо рдЖрджрд┐ред рд╡рд╣ рдпрд╣ рддрдп рдХрд░рддрд╛ рд╣реИ рдХрд┐ iPad рдкрд░ рдкреЙрдкрдУрд╡рд░ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдП: рдХрд┐рд╕ рдлреНрд░реЗрдо рдХреЗ рд╕рд╛рде, рдмрдЯрди рдХреЗ рдХрд┐рд╕ рддрд░рдл рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рдВрдбреЛ рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдореЗрдВ рдХрд▓рдВрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдиреАрдЪреЗ рдЕрдВрдзреЗрд░рд╛ рд╣реЛрддрд╛ рд╣реИред

рд╣рдорд╛рд░реА рд╕рдВрд░рдЪрдирд╛ рд╕рдорд╛рди рд╣реИ: рд╣рдо рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рдЧрд╣рд░рд╛ рдХрд░ рджреЗрдВрдЧреЗ, рдлреНрд░реЗрдо рдХреЛ рдкреВрд░реНрдг рд╕реНрдХреНрд░реАрди рдореЗрдВ рдирд╣реАрдВ рдбрд╛рд▓реЗрдВрдЧреЗ:

presentationController(forPresented:, presenting:, source:)
рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, PresentationController
рд▓реМрдЯрд╛рдПрдВ:
class PanelTransition: NSObject, UIViewControllerTransitioningDelegate { func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { return presentationController = PresentationController(presentedViewController: presented, presenting: presenting ?? source) }
3 рдирд┐рдпрдВрддреНрд░рдХ рдХреНрдпреЛрдВ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд░реЛрдд рдХреНрдпрд╛ рд╣реИ?Source
рдирд┐рдпрдВрддреНрд░рдХ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╣рдордиреЗ рд╢реЛ рдХрд╛ рдПрдиреАрдореЗрд╢рди рдХрд╣рд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдЬреЛ рдирд┐рдпрдВрддреНрд░рдХ рдХрд┐рд╢реНрдд рдореЗрдВ рднрд╛рдЧ рд▓реЗрдЧрд╛, рд╡рд╣ рдкрд╣рд▓реЗ рд╕реЗ definesPresentationContext = true
рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рд╕рд╛рде рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рд╣реИ definesPresentationContext = true
ред рдпрджрд┐ рдирд┐рдпрдВрддреНрд░рдХ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрд╕рд▓реА рд╕рдВрдХреЗрдд рдирд┐рдпрдВрддреНрд░рдХ presenting.
рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рд╣реЛрдЧрд╛ presenting.
рдЕрдм рдЖрдк PresentationController
рд╡рд░реНрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рднрд╡рд┐рд╖реНрдп рдХреЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдлреНрд░реЗрдо рдХрд░реЗрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ frameOfPresentedViewInContainerView
рдкрджреНрдзрддрд┐ рд╣реИред рдирд┐рдпрдВрддреНрд░рдХ рд╕реНрдХреНрд░реАрди рдХреЗ рдирд┐рдЪрд▓реЗ рдЖрдзреЗ рд╣рд┐рд╕реНрд╕реЗ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░рддреЗ рд╣реИрдВ:
class PresentationController: UIPresentationController { override var frameOfPresentedViewInContainerView: CGRect { let bounds = containerView!.bounds let halfHeight = bounds.height / 2 return CGRect(x: 0, y: halfHeight, width: bounds.width, height: halfHeight) } }
рдЖрдк рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрдХреНрд░реАрди рджрд┐рдЦрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдЕрдм рд╣рдо рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЛ рд╕реНрд╡рдпрдВ рджреЗрдЦрддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдХ рджреГрд╢реНрдп рдХреЛ рд╕реНрд╡рдпрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
presentedView
рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдЕрднреА рднреА рдПрдХ рдлреНрд░реЗрдо рд▓рдЧрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред containerViewDidLayoutSubviews
рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рддрд░рд╣ рд╣рдо рд╕реНрдХреНрд░реАрди рд░реЛрдЯреЗрд╢рди рдХрд╛ рдЬрд╡рд╛рдм рджреЗ рд╕рдХрддреЗ рд╣реИрдВ:
рдЕрдм рдЖрдк рджреМрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдПрдиреАрдореЗрд╢рди UIModalTransitionStyle.coverVertical
рд▓рд┐рдП рдорд╛рдирдХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдлреНрд░реЗрдо рдХрд╛ рдЖрдХрд╛рд░ рдЖрдзрд╛ рд╣реЛрдЧрд╛ред
рдкреГрд╖реНрдарднреВрдорд┐ рдХреЛ рдЧрд╣рд░рд╛ рдХрд░реЛ
рдЕрдЧрд▓рд╛ рдХрд╛рдо рдкреГрд╖реНрдарднреВрдорд┐ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдХрд╛рд▓рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬреЛ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЙрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВред
рд╣рдо PresentationController
рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ PanelTransition
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ рдирдП рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдмрджрд▓ PanelTransition
ред рдирдИ рдХрдХреНрд╖рд╛ рдореЗрдВ рдХреЗрд╡рд▓ рдбрд┐рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рд╣реЛрдЧрд╛ред
class DimmPresentationController: PresentationController
рдПрдХ рджреГрд╢реНрдп рдмрдирд╛рдПрдВ рдЬрд┐рд╕реЗ рд╣рдо рд╢реАрд░реНрд╖ рдкрд░ рдУрд╡рд░рд▓реЗ рдХрд░реЗрдВрдЧреЗ:
private lazy var dimmView: UIView = { let view = UIView() view.backgroundColor = UIColor(white: 0, alpha: 0.3) view.alpha = 0 return view }()
рд╣рдо рдЯреНрд░рд╛рдВрд╕реНрдлрд╝реЙрд░реНрдореЗрд╢рди рдПрдиреАрдореЗрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ alpha
рд╡рд┐рдЪрд╛рд░ рдмрджрд▓ рджреЗрдВрдЧреЗред 4 рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ:
presentationTransitionWillBegin
presentationTransitionDidEnd
dismissalTransitionWillBegin
dismissalTransitionDidEnd
рдкрд╣рд▓рд╛ рд╕рдмрд╕реЗ рдХрдард┐рди рд╣реИред рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ dimmView
рдЬреЛрдбрд╝реЗрдВ, рдлреНрд░реЗрдо рдиреАрдЪреЗ рд░рдЦреЗрдВ рдФрд░ рдПрдиреАрдореЗрд╢рди рд╢реБрд░реВ рдХрд░реЗрдВ:
override func presentationTransitionWillBegin() { super.presentationTransitionWillBegin() containerView?.insertSubview(dimmView, at: 0) performAlongsideTransitionIfPossible { [unowned self] in self.dimmView.alpha = 1 } }
рдПрдиреАрдореЗрд╢рди рдХреЛ рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
private func performAlongsideTransitionIfPossible(_ block: @escaping () -> Void) { guard let coordinator = self.presentedViewController.transitionCoordinator else { block() return } coordinator.animate(alongsideTransition: { (_) in block() }, completion: nil) }
рд╣рдордиреЗ containerViewDidLayoutSubviews
dimmView
рдореЗрдВ dimmView
рд▓рд┐рдП рдлреНрд░реЗрдо рд╕реЗрдЯ рдХрд┐рдпрд╛
override func containerViewDidLayoutSubviews() { super.containerViewDidLayoutSubviews() dimmView.frame = containerView!.frame }
рдПрдиреАрдореЗрд╢рди рдХреЛ рдмрд╛рдзрд┐рдд рдФрд░ рд░рджреНрдж рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рд░рджреНрдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ dimmView
рдХреЛ рдкрджрд╛рдиреБрдХреНрд░рдо рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
override func presentationTransitionDidEnd(_ completed: Bool) { super.presentationTransitionDidEnd(completed) if !completed { self.dimmView.removeFromSuperview() } }
рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдореЗрдВ рд░рд┐рд╡рд░реНрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди рдЕрдм рдЖрдкрдХреЛ рдХреЗрд╡рд▓ dimmView
рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрджрд┐ рдПрдиреАрдореЗрд╢рди рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред
override func dismissalTransitionWillBegin() { super.dismissalTransitionWillBegin() performAlongsideTransitionIfPossible { [unowned self] in self.dimmView.alpha = 0 } } override func dismissalTransitionDidEnd(_ completed: Bool) { super.dismissalTransitionDidEnd(completed) if completed { self.dimmView.removeFromSuperview() } }
рдЕрдм рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдбрд┐рдорд┐рдВрдЧ рд╣реЛ рд░рд╣рд╛ рд╣реИред
рд╣рдо рдПрдиреАрдореЗрд╢рди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ
рд╣рдо рдиреАрдЪреЗ рд╕реЗ рдХрдВрдЯреНрд░реЛрд▓рд░ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВ
рдЕрдм рд╣рдо рдирд┐рдпрдВрддреНрд░рдХ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдЪреЗрддрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред PanelTransition
рдХреНрд▓рд╛рд╕ рдореЗрдВ, PanelTransition
рдХреНрд▓рд╛рд╕ PanelTransition
рдЬреЛ рдЙрдкрд╕реНрдерд┐рддрд┐ рдПрдиреАрдореЗрд╢рди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░реЗрдЧрд╛:
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return PresentAnimation() }
рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рд░рд▓ рд╣реИ:
extension PresentAnimation: UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let animator = self.animator(using: transitionContext) animator.startAnimation() } func interruptibleAnimator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating { return self.animator(using: transitionContext) } }
рдХреБрдВрдЬреА рдХреЛрдб рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ:
class PresentAnimation: NSObject { let duration: TimeInterval = 0.3 private func animator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating {
IOS 9 рдореЗрдВ UIViewPropertyAnimator рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИрд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ: рдЖрдкрдХреЛ animateTransition
рдХреЛрдб рдореЗрдВ рдПрдирд┐рдореЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреБрд░рд╛рдиреЗ UIView.animateтАж
api UIView.animateтАж
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬреИрд╕реЗ:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let to = transitionContext.view(forKey: .to)! let finalFrame = transitionContext.finalFrame(for: transitionContext.viewController(forKey: .to)!) to.frame = finalFrame.offsetBy(dx: 0, dy: finalFrame.height) UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [.curveEaseOut], animations: { to.frame = finalFrame }) { (_) in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) } } , `interruptibleAnimator(using transitionContext:)`
рдпрджрд┐ рдЖрдк рдПрдХ рд░реБрдХрд╛рд╡рдЯ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд░реБрдХрд╛рд╡рдЯрдирд┐рдореНрдиреЗрдЯрд░ рд╡рд┐рдзрд┐ рдХреЛ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рд╕рджрд╕реНрдпрддрд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдЫрд┐рдкрд╛рдПрдВ
рд╕рдм рдХреБрдЫ рдПрдХ рд╣реА рд╣реИ, рдХреЗрд╡рд▓ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВред Panel Transition
DismissAnimation
рдХреНрд▓рд╛рд╕ рдмрдирд╛рдПрдБ:
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return DismissAnimation() }
рдФрд░ рд╣рдореЗрдВ рдЗрд╕рдХрд╛ рдПрд╣рд╕рд╛рд╕ рд╣реИред DismissAnimation
рдХрдХреНрд╖рд╛:
class DismissAnimation: NSObject { let duration: TimeInterval = 0.3 private func animator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating { let from = transitionContext.view(forKey: .from)! let initialFrame = transitionContext.initialFrame(for: transitionContext.viewController(forKey: .from)!) let animator = UIViewPropertyAnimator(duration: duration, curve: .easeOut) { from.frame = initialFrame.offsetBy(dx: 0, dy: initialFrame.height) } animator.addCompletion { (position) in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) } return animator } } extension DismissAnimation: UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let animator = self.animator(using: transitionContext) animator.startAnimation() } func interruptibleAnimator(using transitionContext: UIViewControllerContextTransitioning) -> UIViewImplicitlyAnimating { return self.animator(using: transitionContext) } }
рдЗрд╕ рд╕реНрдерд╛рди рдкрд░ рдЖрдк рдкрд╛рд░реНрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкрд░рд┐рджреГрд╢реНрдп рдиреАрдЪреЗ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддрд╛ рд╣реИ;
- рджрд╛рдИрдВ рдУрд░ - рддреНрд╡рд░рд┐рдд рдореЗрдиреВ рдиреЗрд╡рд┐рдЧреЗрд╢рди;
- рдКрдкрд░ - рд╕реВрдЪрдирд╛рддреНрдордХ рд╕рдВрджреЗрд╢:

рдбреЛрдбреЛ рдкрд┐рдЬреНрдЬрд╛ , рд╕реНрдиреИрдХ рдФрд░ рд╕реЗрд╡рдИ
рдЕрдЧрд▓реА рдмрд╛рд░ рд╣рдо рдПрдХ рдЗрд╢рд╛рд░рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рд╕рдорд╛рдкрди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕рдХреЗ рдПрдиреАрдореЗрд╢рди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдкреНрд░рддреАрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдкреВрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧреАрдердм рдкрд░ рд╣реИред
рдФрд░ рдпрд╣рд╛рдБ рд▓реЗрдЦ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рдЖрдпрд╛ред
рдбреЛрдбреЛ рдкрд┐рдЬреНрдЬрд╛ рдореЛрдмрд╛рдЗрд▓ рдЪреИрдирд▓ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдВ ред