How do I make a custom initializer for a UIViewCon

2019-01-13 03:01发布

Apologies if this has been asked before, I've searched around a lot and many answers are from earlier Swift betas when things were different. I can't seem to find a definitive answer.

I want to subclass UIViewController and have a custom initializer to allow me to set it up in code easily. I'm having trouble doing this in Swift.

I want an init() function that I can use to pass a specific NSURL I'll then use with the view controller. In my mind it looks something like init(withImageURL: NSURL). If I add that function it then asks me to add the init(coder: NSCoder) function.

I believe this is because it's marked in the superclass with the required keyword? So I have to do it in the subclass? I add it:

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Now what? Is my special initializer considered a convenience one? A designated one? Do I call a super initializer? An initializer from the same class?

How do I add my special initializer onto a UIViewController subclass?

3条回答
何必那么认真
2楼-- · 2019-01-13 03:39

Convenience initializers are secondary, supporting initializers for a class. You can define a convenience initializer to call a designated initializer from the same class as the convenience initializer with some of the designated initializer’s parameters set to default values. You can also define a convenience initializer to create an instance of that class for a specific use case or input value type.

They are documented here.

查看更多
老娘就宠你
3楼-- · 2019-01-13 03:43

If you need a custom init for a popover for example you can use the following approach:

Create a custom init that uses the super init with nibName and bundle and after that access the view property to force the load of the view hierarchy.

Then in the viewDidLoad function you can configure the views with the parameters passed in the initialization.

import UIKit

struct Player {
    let name: String
    let age: Int
}

class VC: UIViewController {


@IBOutlet weak var playerName: UILabel!

let player: Player

init(player: Player) {
    self.player = player
    super.init(nibName: "VC", bundle: Bundle.main)
    if let view = view, view.isHidden {}
}

override func viewDidLoad() {
    super.viewDidLoad()
    configure()
}

func configure() {
    playerName.text = player.name + "\(player.age)"
}
}

func showPlayerVC() {
    let foo = Player(name: "bar", age: 666)
    let vc = VC(player: foo)
    present(vc, animated: true, completion: nil)
}
查看更多
一纸荒年 Trace。
4楼-- · 2019-01-13 03:48
class ViewController: UIViewController {

    var imageURL: NSURL?

    // this is a convenient way to create this view controller without a imageURL
    convenience init() {
        self.init(imageURL: nil)
    }

    init(imageURL: NSURL?) {
        self.imageURL = imageURL
        super.init(nibName: nil, bundle: nil)
    }

    // if this view controller is loaded from a storyboard, imageURL will be nil

    /* Xcode 6
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    */

    // Xcode 7 & 8
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
查看更多
登录 后发表回答