2014-06-12 13 views
15
@objc(SEPushNoAnimationSegue) 
class SEPushNoAnimationSegue: UIStoryboardSegue { 
    override func perform() { 
     self.sourceViewController.navigationController.pushViewController(self.destinationViewController, animated:false) 
    } 
} 

Nel codice precedente, ho 2 domande: 1). ha un errore di compilazione: 'UINavigationController!' non ha un membro chiamato 'pushViewController'Segmento personalizzato in Swift

Ma in quella classe, ha avuto un metodo pushViewController.

2). Devo aggiungere l'annotazione: @objc (SEPushNoAnimationSegue), altrimenti, nello storyboard, riconosce solo il nome generato a caso, ad esempio _tcxxxxSEPushNoAnimationSegue.

perché questi due problemi si verificano qui?

risposta

32

Issue # 1

UIStoryboardSegue ha un difetto fastidioso: le sue proprietà sourceViewController e destinationViewController vengono digitati come AnyObject! (questo è il caso, anche in Objective-C (tipo Id)) e non come UIViewController, come dovrebbe essere.

Lo stesso difetto crea il caos nel codice perfetto e semplice. Ecco come riscrivere al fine di correggere gli errori di compilazione:

@objc(SEPushNoAnimationSegue) 
class SEPushNoAnimationSegue: UIStoryboardSegue { 
    override func perform() { 
     let src = self.sourceViewController as UIViewController 
     let dst = self.destinationViewController as UIViewController 
     src.navigationController.pushViewController(dst, animated:false) 
    } 
} 

NOTA: Apple fissato questa cosa in iOS 9. sourceViewController e destinationViewController ora sono dichiarate correttamente come UIViewController.

Issue # 2

Il compilatore Swift memorizza i suoi simboli utilizzando il proprio name mangling, e buon ol' Objective-C non lo riconosce in Xcode. Utilizzando un esplicito @obj() risolve il problema.

+0

ho ottenuto questo: Non può scartare Optional.None – fabian

+4

esplicito @objc() - ottimo suggerimento - è quello che ha fatto per me – FiddleMeRagged

+1

la convenzione del nome rapido ha lo scopo di evitare i conflitti con altre importazioni. – Karsten

5

Questo funziona bene per me

@objc(SEPushNoAnimationSegue) class SEPushNoAnimationSegue: UIStoryboardSegue { 

override func perform() { 
    let sourceViewController = self.sourceViewController as UIViewController 
    let destinationViewController = self.destinationViewController as UIViewController 

    sourceViewController.presentViewController(destinationViewController, animated: true, completion: nil) 
} 

} 
1

ancora meglio:

import UIKit 

class CustomSegue: UIStoryboardSegue { 
    override func perform() { 
     self.sourceViewController.presentViewController(self.destinationViewController as UIViewController, animated: false, completion: nil) 
    } 
} 
0

Swift 3.0:

import UIKit 

class CustomNoAnimationSegue: UIStoryboardSegue { 

    override func perform() { 
     if let navigation = source.navigationController { 
      navigation.pushViewController(destination, animated: false) 
     } 
    } 
} 
Problemi correlati