2016-04-14 6 views
8

: Tabii derleyici Ofçağrılması seçici Basit tema motoru inşa ediyorum ve <code>UISwipeGestureRecognizer</code></p> İşte <p>olduğunu <code>UIViewController</code> benim kod ekleyen bir uzantısı olan istiyoruz

protocol Themeable { 
    func themeDidUpdate(currentTheme: Theme) -> Void 
} 

extension Themeable where Self: UIViewController { 
    func switchCurrentTheme() { 
     Theme.switchTheme() 
     themeDidUpdate(Theme.currentTheme) 
    } 

    func addSwitchThemeGestureRecognizer() { 
     let gestureRecognizer = UISwipeGestureRecognizer(target: self, action:#selector(Self.switchCurrentTheme)) 
     gestureRecognizer.direction = .Down 
     gestureRecognizer.numberOfTouchesRequired = 2 
     self.view.addGestureRecognizer(gestureRecognizer) 
    } 
} 

#selector(Self.switchCurrentTheme) bulamıyorum o @objc yönergesi üzerinden maruz değildir. Bu davranışı uzantıma eklemek mümkün mü?

GÜNCELLEME:Theme bir Swift enum, yani emin değilim

cevap

0

Themeable protokolün önünde @objc ekleyemezsiniz ancak

#selector(switchCurrentTheme) 

veya sizin gibi erişebilirsiniz ziyaret edin Bu How to use #selector(myMethodName) in a protocol extension?

+0

@OgreSwamp sizin için çalıştı mı? –

+1

Siz çözüm işe yaramıyor. Sağladığınız bağlantıdaki çözüm benim için de çalışmıyor. Çok özel bir durumu anlatıyor - yöntem çağırma işleminden önce bekliyor. Evet, orada objc hedef/eylem kalıbı kullanarak önleyebilirsiniz ama bildiğim kadarıyla işaret etti dinleyici eklemek için başka bir yolu yoktur. – OgreSwamp

0

ben bir çözüm buldum denemek için bu bağlantıyı başvurabilirsiniz. Mükemmel biri olmayabilir, ama işe yarıyor. Kullandığı çünkü @objc olarak Themeable protokolünü tanımlayamazsınız gibi Swift okunur enum ben için "üst" protokolünü arayıp @objc olarak bu protokolü tanımlamak istediğiniz yöntemi taşınmaya karar verdi. Çalışır ama dürüst olmak gerekirse hiç hazzetmiyorum gibi

@objc protocol ThemeSwitcher { 
    func switchCurrentTheme() 
} 

protocol Themeable: ThemeSwitcher { 
    func themeDidUpdate(currentTheme: Theme) -> Void 
} 

extension Themeable where Self: UIViewController { 
    func switchCurrentTheme() { 
     Theme.switchTheme() 
     themeDidUpdate(Theme.currentTheme) 
    } 

    func addSwitchThemeGestureRecognizer() { 
     let gestureRecognizer = UISwipeGestureRecognizer(target: self, action:#selector(switchCurrentTheme)) 
     gestureRecognizer.direction = .Down 
     gestureRecognizer.numberOfTouchesRequired = 2 
     self.view.addGestureRecognizer(gestureRecognizer) 
    } 
} 
+1

hala benim 'ViewController' uygulayan' Themeable' protokole '@ objc' uygulayamazsınız gibi bu harika bir fikir .. – OgreSwamp

0

Eğer bir @objc birinden olmayan @ objc işlevini diyelim bir sarmalayıcı oluşturma düşündün mü ... görünüyor?

@objc class Wrapper: NSObject { 
    let themeable: Themeable 

    init(themeable: Themeable) { 
     self.themeable = themeable 
    } 

    func switchCurrentTheme() { 
     Theme.switchTheme() 
     themeable.themeDidUpdate(Theme.currentTheme) 
    } 
} 

protocol Themeable { 
    func themeDidUpdate(currentTheme: Theme) -> Void 
} 

extension Themeable where Self: UIViewController { 
    func addSwitchThemeGestureRecognizer() { 
     let wrapper = Wrapper(themeable: self) 
     let gestureRecognizer = UISwipeGestureRecognizer(target: wrapper, action:#selector(Wrapper.switchCurrentTheme)) 
     gestureRecognizer.direction = .Down 
     gestureRecognizer.numberOfTouchesRequired = 2 
     self.view.addGestureRecognizer(gestureRecognizer) 
    } 
} 
+0

çalışmaz, ama çalışmak için alamadım. :(Bunun için –

11

Söz konusu yöntemle UIViewController özel bir uzantı tanımlamak oldu I gelebilir en temiz, çalışma çözüm. private kapsamını sınırlayarak, bu yönteme erişim protokolü tanımlanan kaynak dosya içinde hiç izole Burada göründüğü gibi değil.

protocol Themeable { 
    func themeDidUpdate(currentTheme: Theme) -> Void 
} 

private extension UIViewController { 
    @objc func switchCurrentTheme() { 
     guard let themeableSelf = self as? Themeable else { 
      return 
     } 

     Theme.switchTheme() 
     themeableSelf.themeDidUpdate(Theme.currentTheme) 
    } 
} 

extension Themeable where Self: UIViewController { 
    func addSwitchThemeGestureRecognizer() { 
     let gestureRecognizer = UISwipeGestureRecognizer(target: self, action:#selector(switchCurrentTheme)) 
     gestureRecognizer.direction = .Down 
     gestureRecognizer.numberOfTouchesRequired = 2 
     self.view.addGestureRecognizer(gestureRecognizer) 
    } 
} 
+1

teşekkürler! Bir cazibe gibi çalıştı. :) Swift 3'te UIViewController özel uzantı artık fileprivate yerine olması gerekiyor. Ayrıca, switchCurrentTheme işlevi, internal yerine fileprivate olmalıdır. –

İlgili konular