J'ai une instance de ViewController définie dans un storyboard. Je peux l'initialiser comme suit
var myViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("myViewControllerIdentifier") as! ViewController
Existe-t-il un moyen de remplacer la méthode init de ViewController afin que je puisse l'initialiser à l'aide
var myViewController = ViewController()
J'ai essayé de remplacer init
convenience init() {
self = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
mais le compilateur n'aime pas ça. Des idées?
Un initialiseur de commodité doit toujours déléguer à un initialiseur désigné pour la même classe, et un initialiseur désigné doit appeler un initialiseur de superclasse.
Étant donné que la superclasse n'a pas d'initialiseur approprié, vous seriez probablement mieux servi par une méthode d'usine de classe:
static func instantiate() -> SearchTableViewController
{
return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SearchTableViewController") as! SearchTableViewController
}
puis utilisez:
var myViewController = SearchTableViewController.instantiate()
Une méthode d'usine de classe est la voie à suivre pour l'instant. Voici un protocole que vous pouvez utiliser pour ajouter rapidement la prise en charge de makeFromStoryboard
à tous les UIViewController
.
protocol StoryboardInstantiable {
static var storyboardName: String { get }
static var storyboardBundle: NSBundle? { get }
static var storyboardIdentifier: String? { get }
}
extension StoryboardInstantiable {
static var storyboardBundle: NSBundle? { return nil }
static var storyboardIdentifier: String? { return nil }
static func makeFromStoryboard() -> Self {
let storyboard = UIStoryboard(name: storyboardName, bundle: storyboardBundle)
if let storyboardIdentifier = storyboardIdentifier {
return storyboard.instantiateViewControllerWithIdentifier(storyboardIdentifier) as! Self
} else {
return storyboard.instantiateInitialViewController() as! Self
}
}
}
Exemple:
extension MasterViewController: StoryboardInstantiable {
static var storyboardName: String { return "Main" }
static var storyboardIdentifier: String? { return "Master" }
}
Dans le cas où le contrôleur de vue est le contrôleur de vue initial dans le storyboard, vous pouvez simplement ignorer storyboardIdentifier
.
Dans le cas où tous les contrôleurs de vue sont dans le même storyboard, vous pouvez également remplacer storyboardName
sous l'extension StoryboardInstantiable
et renvoyer le nom.