2016-12-18 3 views
7

Я разрабатываю библиотеку, и я хочу предоставить настраиваемый переход между двумя контроллерами представлений по умолчанию, пользователь может также предоставить свою собственную реализацию, первая идея, которая приходит мне на ум, состоит в том, чтобы переопределить UIViewController и реализовать UIViewControllerTransitioningDelegate, а затем пользователи могут подклассифицировать мой CustomTransitionViewController, это лучший способ сделать это? любые ограничения? есть ли более элегантный способ использования только протоколов, например, при реализации по умолчанию?Default Custom Transition для UIViewController

import UIKit 

class CustomTransitionViewController: UIViewController, UIViewControllerTransitioningDelegate { 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     self.transitioningDelegate = self 
    } 

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil:Bundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     self.transitioningDelegate = self 
    } 

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 
} 

ответ

0

Вы также можете просто сделать расширение для UIViewController, который делает все, что вам нужно, и дополнительно соответствует вашему протоколу, который позволяет пользователю т.е. отключитьпо умолчанию переходов.

В качестве примера:

protocol ThorsHammer { 
    var isDefaultTransitionEnabled: Bool { get set } 
} 

extension UIViewController: ThorsHammer { 
    var isDefaultTransitionEnabled: Bool { /* this part sucks */ } 

    // Check if the default transition should happen and 
    // do some transition magic 
} 

Как оных хранятся свойства к расширений, вы могли бы посмотреть на this.

Все это, если вы можете найти способ, чтобы установить transitioningDelegate как-то в расширения, в противном случае вы будете иметь подкласс.

5

Я думаю, что один из самых элегантных (и ориентированных на протокол) способов сделать это будет с расширением UIViewControllerTransitioningDelegate. Расширьте протокол и предоставите стандартную реализацию для animationController(forPresented: presenting: source:) и animationController(forDismissed:). Расширение будет выглядеть примерно так:

extension UIViewControllerTransitioningDelegate where Self: UIViewController { 
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 
} 

А потом сказать своим пользователям расширить свои контроллеры просмотра, чтобы соответствовать этому протоколу. Так как вы уже реализованы только требования расширения для протокола, все, что нужно сделать, это добавить объявление на соответствие, например, так:

class MyViewController: UIViewController, UIViewControllerTransitioningDelegate { } 

Если вы хотите расширить все UIViewController s, чтобы сделать это, вы можете сделать это с пробел:

extension UIViewController: UIViewControllerTransitioningDelegate { } 

Это должно сработать. На мой взгляд, это очень чистое, элегантное решение, которое не требует ненужного подкласса. Это также облегчает предоставление различных реализаций animationController(forPresented: presenting: source:) и animationController(forDismissed:) в каждом контроллере представления. Ваши пользователи могут просто добавить свои собственные реализации двух вышеупомянутых функций, где бы они ни захотели. Кроме того, вам не нужно иметь дело с беспорядочным объектом Objective C, таким как связанные объекты.

Если вы предоставляете эту функциональность в каком-то расфасованном комплекте, и вы хотите скрыть базовую реализацию, вы можете объявить свой собственный протокол, сделать его подпротоколом в UIViewControllerTransitioningDelegate, расширить его аналогично, и ваши пользователи будут соответствовать пользовательский протокол вместо UIViewControllerTransitioningDelegate:

protocol MyProtocol: UIViewControllerTransitioningDelegate { 
    //Add your own requirements (if you have any). 
} 

extension MyProtocol where Self: UIViewController { 
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) 
    } 

    //Satisfy your requirements (or let your users do it). 
} 

class MyViewController: UIViewController, MyProtocol { } 

extension UIViewController: MyProtocol { } 

Какого бы маршрутом вы принимаете, это решение дает вам то, что вы хотите, не делая вы имеете дело с посторонними подклассами или уродливыми понятиями Objective C. Удачи!

 Смежные вопросы

  • Нет связанных вопросов^_^