Providing my own initializer for UICollectionViewFlowLayout

时间:2015-07-28 22:39:15

标签: ios swift

I'd like to provide my own initializer for my UICollectionViewFlowLayout subclass, for the purposes of calculating my itemSize property at runtime to scale my cells properly for different screen sizes. I understand that the simplest way to do so, is to adjust the default UICollectionViewFlowLayout from the UICollectionViewController like this:

//in UICollectionViewController
override func viewDidLoad() {
    super.viewDidLoad()
    let someWidth = ...
    let someHeight = ...
    let layout = collectionViewLayout as! UICollectionViewFlowLayout
    layout.itemSize = CGSize(width: someWidth, height: someHeight)
}

However, I need to subclass UICollectionViewFlowLayout for the purposes of some custom layout for my UICollectionReusableView, so I thought it would be nice to declare the itemSize property in my layout subclass.

I am trying to make my own initializer, like so:

override init() {
    super.init()
    itemSize = CGSizeMake(someWidth, someHeight)
}

but I am greeted with the requirement:

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

When I attempt to load this viewController, I'm greeted with the fatalError. Next, I try to simply let the super implementation deal with it:

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

I recall various bits of information that is forcing my mind in a state of caution, something along the lines of: If one decides to subclassing something that requires the NSCoding things, one must do something to the variables that I added to the subclass.

Can anyone advise me on this?

1 个答案:

答案 0 :(得分:2)

-- EDIT --

Is this what you're looking for?

class HmIsThisOK: UICollectionViewFlowLayout {
    var myCustomSize: CGSize = CGSizeMake(60.0, 23.5)
    override var itemSize: CGSize {
        get { return myCustomSize }
        set { myCustomSize = newValue }
    }
}

or does it just make sense to follow the usual protocol of initializing itemSize in your implementation of prepareForLayout()?

If none of that works for you, it's perfectly safe to do the required init junk and just add your code to the end of it after calling super.init(...). You're not concerned with tying your custom init to the coding/encoding process, which has to do from awakening from the Nib file (usually Main.storyboard). Because the two inits() are required, you usually factor out your custom init code into a helper method.

Finally, If you are indeed awakening this object from the Nib file, you can use an overridden awakeFromNib() function to do custom initialization, without worrying about the init() prickliness.