рдХрд╕реНрдЯрдо рдПрдирд┐рдореЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП UIViewPropertyAnimator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдПрдирд┐рдореЗрд╢рди рдмрдирд╛рдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред рд╡реЗ iOS рдорд╛рдирд╡ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рджрд┐рд╢рд╛рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИрдВред рдПрдирд┐рдореЗрд╢рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдмрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХрдо рдЙрдмрд╛рдК рдмрдирд╛рддреЗ рд╣реИрдВред

IOS рдореЗрдВ рдПрдиреАрдореЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВред рд╕рдВрднрд╡рддрдГ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рддрд░реАрдХрд╛ UIView.animate (withDuration: animations :) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ ред рдЖрдк CABasicAnimation рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЫрд╡рд┐ рдкрд░рдд рдХреЛ рдПрдирд┐рдореЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, UIKit рдЖрдкрдХреЛ UIViewControllerTransitioningDelegate рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╕реНрдЯрдо рдПрдирд┐рдореЗрд╢рди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдПрдХ рдФрд░ рд░реЛрдорд╛рдВрдЪрдХ рддрд░реАрдХреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд░реНрдЪрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ - UIViewPropertyAnimator ред рдпрд╣ рд╡рд░реНрдЧ рдЕрдкрдиреЗ рдкреВрд░реНрд╡рд╡рд░реНрддреА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдИ рдЕрдзрд┐рдХ рдкреНрд░рдмрдВрдзрди рдХрд╛рд░реНрдп рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, UIView.animat eред рдЕрд╕реНрдерд╛рдпреА, рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдФрд░ рдмрд╛рдзрд┐рдд рдПрдирд┐рдореЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдирд┐рдореЗрдЯрд░ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдмрджрд▓рдирд╛ рд╕рдВрднрд╡ рд╣реИред

рдкреЗрд╢ рд╣реИ UIViewPropertyAnimator


UIViewPropertyAnimator рдХреЛ iOS 10 рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рдЖрдкрдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ-рдУрд░рд┐рдПрдВрдЯреЗрдб рддрд░реАрдХреЗ рд╕реЗ рдПрдирд┐рдореЗрд╢рди рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЖрдЗрдП UIViewPropertyAnimator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдП рдЧрдП рдПрдХ рдПрдиреАрдореЗрд╢рди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ ред

рдЫрд╡рд┐

рдпрд╣ рдХреИрд╕реЗ рд╣реИ рдЬрдм рдпрд╣ UIView рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рдерд╛ред

UIView.animate(withDuration: 0.3) { view.frame = view.frame.offsetBy(dx: 100, dy: 0) } 

рдФрд░ рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ UIViewPropertyAnimator рдХреЗ рд╕рд╛рде:

 let animator = UIViewPropertyAnimator(duration:0.3, curve: .linear) { view.frame = view.frame.offsetBy(dx:100, dy:0) } animator.startAnimation() 

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

рдЫрд╡рд┐

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

рдЗрдВрдЯрд░рдПрдХреНрдЯрд┐рд╡ рдФрд░ рдмрд╛рдзрд┐рдд рдПрдиреАрдореЗрд╢рди


рдХреНрдпрд╛ рдЖрдкрдХреЛ рдХреНрд▓рд╛рд╕рд┐рдХ "рдлрд┐рдВрдЧрд░ рд╕реНрд╡рд╛рдЗрдк рдЯреВ рдЕрдирд▓реЙрдХ рдбрд┐рд╡рд╛рдЗрд╕" рдЗрд╢рд╛рд░рд╛ рдпрд╛рдж рд╣реИ? рдпрд╛ рдЗрд╢рд╛рд░рд╛ "рдирд┐рдпрдВрддреНрд░рдг рдХреЗрдВрджреНрд░ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░реАрди рдкрд░ рдиреАрдЪреЗ рд╕реЗ рдКрдкрд░ рддрдХ рдЕрдкрдиреА рдЙрдВрдЧрд▓реА рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ"? рдпреЗ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдПрдиреАрдореЗрд╢рди рдХреЗ рдорд╣рд╛рди рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред рдЖрдк рдЕрдкрдиреА рдЙрдВрдЧрд▓реА рд╕реЗ рдЫрд╡рд┐ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдлрд┐рд░ рдЗрд╕реЗ рдЬрд╛рд░реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЫрд╡рд┐ рдЕрдкрдиреА рдореВрд▓ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреАред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдПрдиреАрдореЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдЫрд╡рд┐ рдХреЛ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреА рдЙрдВрдЧрд▓реА рд╕реЗ рдЗрд╕реЗ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред

UIView рдПрдирд┐рдореЗрд╢рди рдПрдирд┐рдореЗрд╢рди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдкреНрд░рддрд┐рд╢рдд рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рд▓реВрдк рдХреЗ рдмреАрдЪ рдореЗрдВ рдПрдиреАрдореЗрд╢рди рдХреЛ рд░реЛрдХ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд░реБрдХрд╛рд╡рдЯ рдХреЗ рдмрд╛рдж рдЗрд╕рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо UIViewPropertyAnimator рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред рдЕрдЧрд▓рд╛, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдХреБрдЫ рдЪрд░рдгреЛрдВ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡, рдмрд╛рдзрд┐рдд рдПрдиреАрдореЗрд╢рди рдФрд░ рд░рд┐рд╡рд░реНрд╕ рдПрдиреАрдореЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдкреНрд░рдХреНрд╖реЗрдкрдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рддреИрдпрд╛рд░реА


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

рд╕реБрдВрджрд░ рдПрдирд┐рдореЗрд╢рди рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдпрд╣рд╛рдБ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЖрдк рдЗрд╕реЗ Xcode рдореЗрдВ рдЦреЛрд▓рдХрд░ рдХреНрдпрд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

  1. ViewController.swift : UICollectionView рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдирд┐рдпрдВрддреНрд░рдХ рдЬреЛ рд╕рд┐рдЯреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдПрдХ рд╕рд░рдгреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
  2. CityCollectionViewCell.swift: рд╕рд┐рдЯреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд▓ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд░рд┐рд╡рд░реНрддрди рдЗрд╕ рд╡рд░реНрдЧ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрдВрдЧреЗред рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡рд┐рд╡рд░рдгрд▓реЗрдмрд▓ рдФрд░ рдХреНрд▓реЛрдЬрдмрдЯрди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдХреНрд╖рд╛ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдЫрд┐рдкрд╛рдП рдЬрд╛рдПрдВрдЧреЗред рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВ, рд╡реЗ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреЗред рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣ рджреГрд╢реНрдп рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рдЧреБрдг рднреА рд╣реИрдВред рдмрд╛рдж рдореЗрдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдиреАрдореЗрд╢рди рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
  3. CityCollectionViewFlowLayout.swift: рдпрд╣ рд╡рд░реНрдЧ рдХреНрд╖реИрддрд┐рдЬ рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рд╣рдо рдЗрд╕реЗ рдЕрднреА рддрдХ рдирд╣реАрдВ рдмрджрд▓реЗрдВрдЧреЗред
  4. City.swift : рдореБрдЦреНрдп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдбрд▓ рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ ViewController рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
  5. Main.storyboard: рд╡рд╣рд╛рдБ рдЖрдк ViewController рдФрд░ CityCollectionViewCell рдХреЗ рд▓рд┐рдП рдпреВрдЬрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЗрдП рдирдореВрдирд╛ рдЖрд╡реЗрджрди рдмрдирд╛рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред

cityguideapp-iphone8

рддреИрдирд╛рддреА рдФрд░ рдкрддрди рдПрдиреАрдореЗрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╢рд╣рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рд▓реЗрдХрд┐рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЕрдм рдЖрдкрдХреЛ рдкреНрд░рддреНрдпреЗрдХ рд╢рд╣рд░ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдПрдХ рд╕реЗрд▓ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИред рдЖрд╡реЗрджрди рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдпрд╣рд╛рдБ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

рдЫрд╡рд┐

рдПрдиреАрдореЗрд╢рди рдЕрдЪреНрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИ, рд╣реИ рдирд╛? рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдХреБрдЫ рдЦрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл UIViewPropertyAnimator рдХрд╛ рдореВрд▓ рддрд░реНрдХ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдиреАрдореЗрд╢рди рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдПрдХ рд╕рдВрдЧреНрд░рд╣ рджреГрд╢реНрдп рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВ (_: didSelectItemAt) , ViewController рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЯреБрдХрдбрд╝рд╛ рдЬреЛрдбрд╝реЗрдВ:

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let selectedCell = collectionView.cellForItem(at: indexPath)! as! CityCollectionViewCell selectedCell.toggle() } 

рдЕрдм рд╣рдореЗрдВ рдЯреЙрдЧрд▓ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЪрд▓рд┐рдП CityCollectionViewCell.swift рдкрд░ рдЬрд╛рдПрдБ рдФрд░ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВред

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

 private enum State { case expanded case collapsed var change: State { switch self { case .expanded: return .collapsed case .collapsed: return .expanded } } } 

CityCollectionViewCell рд╡рд░реНрдЧ рдореЗрдВ рдПрдиреАрдореЗрд╢рди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЧреБрдг рдЬреЛрдбрд╝реЗрдВ:

 private var initialFrame: CGRect? private var state: State = .collapsed private lazy var animator: UIViewPropertyAnimator = { return UIViewPropertyAnimator(duration: 0.3, curve: .easeInOut) }() 

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

рдЕрдм рдЯреЙрдЧрд▓ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ рдирдЬрджреАрдХреА рд╡рд┐рдзрд┐ рд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

 @IBAction func close(_ sender: Any) { toggle() } func toggle() { switch state { case .expanded: collapse() case .collapsed: expand() } } 

рдлрд┐рд░ рд╣рдо рджреЛ рдФрд░ рддрд░реАрдХреЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ: рд╡рд┐рд╕реНрддрд╛рд░ () рдФрд░ рдкрддрди () ред рд╣рдо рдЙрдирдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░ () рд╡рд┐рдзрд┐ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

 private func expand() { guard let collectionView = self.collectionView, let index = self.index else { return } animator.addAnimations { self.initialFrame = self.frame self.descriptionLabel.alpha = 1 self.closeButton.alpha = 1 self.layer.cornerRadius = 0 self.frame = CGRect(x: collectionView.contentOffset.x, y:0, width: collectionView.frame.width, height: collectionView.frame.height) if let leftCell = collectionView.cellForItem(at: IndexPath(row: index - 1, section: 0)) { leftCell.center.x -= 50 } if let rightCell = collectionView.cellForItem(at: IndexPath(row: index + 1, section: 0)) { rightCell.center.x += 50 } self.layoutIfNeeded() } animator.addCompletion { position in switch position { case .end: self.state = self.state.change collectionView.isScrollEnabled = false collectionView.allowsSelection = false default: () } } animator.startAnimation() } 

рдХрд┐рддрдирд╛ рдХреЛрдб рд╣реИ? рдореБрдЭреЗ рд╕рдордЭрд╛рдПрдВ рдХрд┐ рдХрджрдо рд╕реЗ рдХрджрдо рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ:

  1. рдкрд╣рд▓реЗ, рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рдВрдЧреНрд░рд╣ рджреГрд╢реНрдп рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рд╢реВрдиреНрдп рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИрдВред рдЕрдиреНрдпрдерд╛, рд╣рдо рдПрдиреАрдореЗрд╢рди рд╢реБрд░реВ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред
  2. рдЕрдЧрд▓рд╛, animator.addAnimations рдкрд░ рдХреЙрд▓ рдХрд░рдХреЗ рдПрдиреАрдореЗрд╢рди рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред
  3. рдЗрд╕рдХреЗ рдмрд╛рдж, рд╡рд░реНрддрдорд╛рди рдлрд╝реНрд░реЗрдо рдХреЛ рд╕рд╣реЗрдЬреЗрдВ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдиреНрд╡реЗрдВрд╢рди рдПрдиреАрдореЗрд╢рди рдореЗрдВ рдЗрд╕реЗ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  4. рдлрд┐рд░ рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд░рдгрд▓реЗрдмреЗрд▓ рдФрд░ рдХреНрд▓реЛрдЬрд╝рдмрдЯрди рдХреЗ рд▓рд┐рдП рдЕрд▓реНрдлрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред
  5. рдЕрдЧрд▓рд╛, рдЧреЛрд▓ рдХреЛрдиреЗ рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рд╕реЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдлреНрд░реЗрдо рд╕реЗрдЯ рдХрд░реЗрдВред рд╕реЗрд▓ рдХреЛ рдлреБрд▓ рд╕реНрдХреНрд░реАрди рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
  6. рдЕрдЧрд▓рд╛ рд╣рдо рдкрдбрд╝реЛрд╕реА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
  7. рдЕрдм рд╕рдВрдЧреНрд░рд╣ рдЫрд╡рд┐ рдХреЗ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЛ рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП animator.addComplete () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред рдпрд╣ рд╕реЗрд▓ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рджреМрд░рд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЗрд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИред рд╕реЗрд▓ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рднреА рдмрджрд▓реЗрдВред рд╕реЗрд▓ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдПрдиреАрдореЗрд╢рди рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред

рдЕрдм рдПрдХ рдХрдиреНрд╡реЗрдВрд╢рди рдПрдиреАрдореЗрд╢рди рдЬреЛрдбрд╝реЗрдВред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рд╣рдо рд╕реЗрд▓ рдХреЛ рдЙрд╕рдХреА рдкрд┐рдЫрд▓реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 private func collapse() { guard let collectionView = self.collectionView, let index = self.index else { return } animator.addAnimations { self.descriptionLabel.alpha = 0 self.closeButton.alpha = 0 self.layer.cornerRadius = self.cornerRadius self.frame = self.initialFrame! if let leftCell = collectionView.cellForItem(at: IndexPath(row: index - 1, section: 0)) { leftCell.center.x += 50 } if let rightCell = collectionView.cellForItem(at: IndexPath(row: index + 1, section: 0)) { rightCell.center.x -= 50 } self.layoutIfNeeded() } animator.addCompletion { position in switch position { case .end: self.state = self.state.change collectionView.isScrollEnabled = true collectionView.allowsSelection = true default: () } } animator.startAnimation() } 

рдЕрдм рдЖрд╡реЗрджрди рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЪрд▓рд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рд╕реЗрд▓ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдФрд░ рдЖрдк рдПрдиреАрдореЗрд╢рди рджреЗрдЦреЗрдВрдЧреЗред рдЫрд╡рд┐ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдКрдкрд░реА рджрд╛рдПрдВ рдХреЛрдиреЗ рдореЗрдВ рдХреНрд░реЙрд╕ рдЖрдЗрдХрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рдЬреЗрд╕реНрдЪрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЬреЛрдбрд╝рдирд╛


рдЖрдк UIView.animate рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рджрд╛рд╡рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред UIViewPropertyAnimator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ ?

рдЦреИрд░, рдПрдиреАрдореЗрд╢рди рдХреЛ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИред UIPanGestureRecognizer рдФрд░ popupOffset рдирд╛рдордХ рдПрдХ рдирдИ рдкреНрд░реЙрдкрд░реНрдЯреА рдЬреЛрдбрд╝реЗрдВ, рдЬрд┐рд╕рд╕реЗ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рд╕реЗрд▓ рдХреЛ рдХрд┐рддрдирд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЪрд▓рд┐рдП CityCollectionViewCell рд╡рд░реНрдЧ рдореЗрдВ рдЗрди рдЪрд░реЛрдВ рдХреЛ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 private let popupOffset: CGFloat = (UIScreen.main.bounds.height - cellSize.height)/2.0 private lazy var panRecognizer: UIPanGestureRecognizer = { let recognizer = UIPanGestureRecognizer() recognizer.addTarget(self, action: #selector(popupViewPanned(recognizer:))) return recognizer }() 

рдлрд┐рд░ рд╕реНрд╡рд╛рдЗрдк рдкрд░рд┐рднрд╛рд╖рд╛ рджрд░реНрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:

 override func awakeFromNib() { self.addGestureRecognizer(panRecognizer) } 

рдЕрдм рдЖрдкрдХреЛ рд╕реНрд╡рд╛рдЗрдк рдЬреЗрд╕реНрдЪрд░ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреЙрдкрдЕрдк рд╡реНрдпреВрдкреНрдб рд╡рд┐рдзрд┐ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ CityCollectionViewCell рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВ:

 @objc func popupViewPanned(recognizer: UIPanGestureRecognizer) { switch recognizer.state { case .began: toggle() animator.pauseAnimation() case .changed: let translation = recognizer.translation(in: collectionView) var fraction = -translation.y / popupOffset if state == .expanded { fraction *= -1 } animator.fractionComplete = fraction case .ended: animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) default: () } } 

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

рдЖрд╡реЗрджрди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рдЗрд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрд▓ рдХреЛ рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░ рдЗрд╕реЗ рдЧрд┐рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд╕реЗрд▓ рдХреЛ рдиреАрдЪреЗ рдЦреАрдВрдЪреЗрдВред

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

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдиреАрдореЗрд╢рди рдХреА рдкреНрд░рдЧрддрд┐ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдиреАрдореЗрд╢рди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдкреНрд░рддрд┐рд╢рдд рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдореВрд▓реНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, CityCollectionViewCell рдореЗрдВ рдПрдХ рдирдИ рд╕рдВрдкрддреНрддрд┐ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:

 private var animationProgress: CGFloat = 0 

рдлрд┐рд░ рдкреНрд░рдЧрддрд┐ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рдХреЗ рд╕рд╛рде рдкреЙрдкрдЕрдк рд╡реНрдпреВ рд╡рд┐рдзрд┐ рдХреЗ .began рдмреНрд▓реЙрдХ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ:

 animationProgress = animator.fractionComplete 

рдкреВрд░реНрдг рдмреНрд▓реЙрдХ рдореЗрдВ, рдЖрдкрдХреЛ рдкреВрд░реНрдгрддрд╛ рдХреЗ рдкреНрд░рддрд┐рд╢рдд рдХреА рд╕рд╣реА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

 animator.fractionComplete = fraction + animationProgress 

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

рдЫрд╡рд┐

рдПрдиреАрдореЗрд╢рди рд░рд┐рд╡рд░реНрд╕


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

 let velocity = recognizer.velocity(in: self) let shouldComplete = velocity.y > 0 if velocity.y == 0 { animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) break } switch state { case .expanded: if !shouldComplete && !animator.isReversed { animator.isReversed = !animator.isReversed } if shouldComplete && animator.isReversed { animator.isReversed = !animator.isReversed } case .collapsed: if shouldComplete && !animator.isReversed { animator.isReversed = !animator.isReversed } if !shouldComplete && animator.isReversed { animator.isReversed = !animator.isReversed } } animator.continueAnimation(withTimingParameters: nil, durationFactor: 0) 

рдЕрдм рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╢рд╛рд░реЗ рдХреА рдЧрддрд┐ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдПрдиреАрдореЗрд╢рди рдХреЛ рдЙрд▓рдЯ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдФрд░ рдЕрдВрдд рдореЗрдВ, .changed рдмреНрд▓реЙрдХ рдореЗрдВ рдХреЛрдб рдХреА рдПрдХ рдФрд░ рд▓рд╛рдЗрди рдбрд╛рд▓реЗрдВред рдЗрд╕ рдХреЛрдб рдХреЛ animator.fractionComplete рдЧрдгрдирд╛ рдХреЗ рджрд╛рдИрдВ рдУрд░ рд░рдЦреЗрдВред

 if animator.isReversed { fraction *= -1 } 

рдЪрд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓рд╛рддреЗ рд╣реИрдВред рдЕрдм рд╕рдм рдХреБрдЫ рдмрд┐рдирд╛ рдЕрд╕рдлрд▓ рд╣реБрдП рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЫрд╡рд┐

рдкреИрди рдЬреЗрд╕реНрдЪрд░ рдХреЛ рдареАрдХ рдХрд░реЗрдВ


рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ UIViewPropertyAnimator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдиреАрдореЗрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреВрд░рд╛ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдЕрдкреНрд░рд┐рдп рдЧрд▓рддреА рд╣реИред рдЖрдк рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп рдЙрд╕рд╕реЗ рдорд┐рд▓реЗ рд╣реЛрдВрдЧреЗред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╕реЗрд▓ рдХреЛ рдХреНрд╖реИрддрд┐рдЬ рд░реВрдк рд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред рдЪрд▓реЛ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд╛рдПрдВ / рджрд╛рдПрдВ рд╕реНрд╡рд╛рдЗрдк рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

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

рд╣рд╛рд▓рд╛рдБрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрднреА рднреА рдКрдкрд░ / рдиреАрдЪреЗ рдХрдХреНрд╖реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╢рд╣рд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖реЛрдВ рдХреЗ рдмреАрдЪ рдХреА рдЬрдЧрд╣, рдореИрдВ рдЕрднреА рднреА рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдмреБрд░реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреА рддрд░рд╣ рдирд╣реАрдВ рд╣реВрдВред рдЪрд▓реЛ рдЗрд╕реЗ рдареАрдХ рдХрд░рддреЗ рд╣реИрдВред

рд╕рдВрдШрд░реНрд╖реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдкрджреНрдзрддрд┐ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЧреЗрд╕реНрдЯрд░реЛрдЧрдирд╛рдЗрдЬрд╝рд░рд╢реЛрд▓реНрдбрдмрд┐рди (_ :) рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╢рд╛рд░рд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рд╕реНрдкрд░реНрд╢ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рд╡рд┐рдзрд┐ рдореЗрдВ рдЧрд▓рдд рд▓реМрдЯрддреЗ рд╣реИрдВ, рддреЛ рд╣рд╛рд╡рднрд╛рд╡ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╕реНрдкрд░реНрд╢ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░ рджреЗрдЧрд╛ред рддреЛ рд╣рдо рдЬреЛ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рд╡рд╣ рд╣рдорд╛рд░реЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреИрдиреЛрд░рдорд╛ рдорд╛рдиреНрдпрддрд╛ рдЙрдкрдХрд░рдг рдХреЛ рдХреНрд╖реИрддрд┐рдЬ рдЖрдВрджреЛрд▓рдиреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рджреЗрддрд╛ рд╣реИред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкреИрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдкреИрдирдЖрд░рдХреЛрдЧрдирд╛рдЗрдЬрд╝рд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдореЗрдВ рдХреЛрдб рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рдбрд╛рд▓реЗрдВ (рдЖрдк рд░рд┐рдЯрд░реНрди рд░рд┐рдХреЙрдЗрдбрд░ рдХреЗ рдареАрдХ рдкрд╣рд▓реЗ рдХреЛрдб рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ :

 recognizer.delegate = self 

рдлрд┐рд░, рд╣рдо рдЬреЗрд╕реЗрд░реЛрдЧреЗрдирд╛рдЗрдЬрд░рд╢реЛрд▓реНрдбрдмрд┐рди (_ :) рд╡рд┐рдзрд┐ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

 override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { return abs((panRecognizer.velocity(in: panRecognizer.view)).y) > abs((panRecognizer.velocity(in: panRecognizer.view)).x) } 

рдпрджрд┐ рдЗрд╕рдХреА рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдЧрддрд┐ рдХреНрд╖реИрддрд┐рдЬ рдЧрддрд┐ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рд╣рдо рдЦреБрд▓реЗрдВрдЧреЗ / рдмрдВрдж рдХрд░реЗрдВрдЧреЗред

рд╡рд╛рд╣! рдЪрд▓реЛ рдлрд┐рд░ рд╕реЗ рдЖрд╡реЗрджрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВред рдЕрдм рдЖрдк рдХрдХреНрд╖реЛрдВ рдореЗрдВ рдмрд╛рдПрдБ / рджрд╛рдПрдБ рд╕реНрд╡рд╛рдЗрдк рдХрд░рдХреЗ рд╢рд╣рд░реЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЫрд╡рд┐

рдмреЛрдирд╕: рдХрд╕реНрдЯрдо рд╕рд┐рдВрдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ


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

рдЖрдорддреМрд░ рдкрд░, рдЖрдкрдХреЛ UIView.animation рдХреЛ CabasicAnimation рдореЗрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдЗрд╕реЗ CATransaction рдореЗрдВ рд▓рдкреЗрдЯрдирд╛ рдЪрд╛рд╣рд┐рдПред UIViewPropertyAnimator рдХреЗ рд╕рд╛рде, рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд╕реНрдЯрдо рдЯрд╛рдЗрдорд┐рдВрдЧ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЯрд╛рдЗрдорд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рдВрд╕ (рдпрд╛ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдХрдо рдХрд░рдирд╛) рдХреЛ рдПрдиреАрдореЗрд╢рди рд╕реНрдкреАрдб рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдордЭрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдПрдирд┐рдореЗрдЯреЗрдб рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рджрд░ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЪрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ: easInOut, easIn, easOut, рд░реИрдЦрд┐рдХред

рдЗрд╕ рд╕рдордп рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдирд┐рдореЗрдЯрд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рдмрджрд▓реЗрдВ (рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдмреЗрдЬрд┐рдпрд░ рдХреНрдпреВрдмрд┐рдХ рд╡рдХреНрд░ рдХреЛ рдЦреАрдВрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ) рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ:

 private lazy var animator: UIViewPropertyAnimator = { let cubicTiming = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.17, y: 0.67), controlPoint2: CGPoint(x: 0.76, y: 1.0)) return UIViewPropertyAnimator(duration: 0.3, timingParameters: cubicTiming) }() 

рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдШрди рддреБрд▓реНрдпрдХрд╛рд▓рди рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рд╡рд╕рдВрдд рддреБрд▓реНрдпрдХрд╛рд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

  let springTiming = UISpringTimingParameters(mass: 1.0, stiffness: 2.0, damping: 0.2, initialVelocity: .zero) 

рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


UIViewPropertyAnimator рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЖрдк рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдПрдирд┐рдореЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд┐рд░ рд╕реНрдХреНрд░реАрди рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЛ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдпрд╣ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдХрд┐ рдЖрдкрдиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреНрдпрд╛ рд╕реАрдЦрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛, рдореБрдЭреЗ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдиреАрдЪреЗ рдЯрд┐рдкреНрдкрдгреА рдЫреЛрдбрд╝ рдХрд░ рдмрддрд╛рдПрдВред

рдПрдХ рд╕рдВрджрд░реНрдн рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣рд╛рдВ рдЖрдк рдЕрдВрддрд┐рдо рдбреНрд░рд╛рдлреНрдЯ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЧреЗ рдХреЗ рд▓рд┐рдВрдХ


UIKit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреЗрд╢реЗрд╡рд░ рдПрдирд┐рдореЗрд╢рди - https://developer.apple.com/videos/play/wwdc2017/230/

Apple рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП UIViewPropertyAnimator рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг - https://developer.apple.com/documentation/uikit/uiviewpropertyanimator

Source: https://habr.com/ru/post/hi458970/


All Articles