Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
252 views
in Technique[技术] by (71.8m points)

ios - Is there a more optimised/ efficient way to create custom UIView directly from XIB, in storyboard?

Assume I have a custom UIView class ColorWheelView.swift and XIB ColorWheelView.xib.

To create an custom UIView from XIB via code, here's the common practice


Via Code

extension UIView {
    static func instanceFromNib() -> Self {
        return getUINib().instantiate(withOwner: self, options: nil)[0] as! Self
    }
    
    static func getUINib() -> UINib {
        return UINib(nibName: String(describing: self), bundle: nil)
    }
}

// Create ColorWheelView from XIB.
let colorWheelView = ColorWheelView.instanceFromNib()

Via Storyboard (Doesn't look like a right way)

But, how about Storyboard? What if I use ColorWheelView as a subview in Storyboard? How can I inform Storyboard that ColorWheelView should be constructed directly from ColorWheelView.xib?

enter image description here

A common way I have seen so far is discussed in https://stackoverflow.com/a/34524346/72437 and https://stackoverflow.com/a/34524583/72437

import UIKit

class ColorWheelView: UIView {

    let nibName = "ColorWheelView"
    var contentView: UIView?

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

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    func commonInit() {
        guard let view = loadViewFromNib() else { return }
        view.frame = self.bounds
        self.addSubview(view)
        contentView = view
    }

    func loadViewFromNib() -> UIView? {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: nibName, bundle: bundle)
        return nib.instantiate(withOwner: self, options: nil).first as? UIView
    }
}

But, such code just doesn't look right to me. It merely

  1. Storyboard creates a "parent" ColorWheelView without using XIB.
  2. Then, "parent" ColorWheelView creates another "child" ColorWheelView from XIB, and used it as subview of itself.
  3. Doesn't seem like an optimised way, as now we are having 2 instances of ColorWheelView.

Is there a better way, to tell Storyboard that I want to create a custom subview from an XIB?

question from:https://stackoverflow.com/questions/65867880/is-there-a-more-optimised-efficient-way-to-create-custom-uiview-directly-from-x

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
import UIKit

@IBDesignable class ColorWheelView: UIView {

let nibName = "ColorWheelView"
var contentView: UIView?

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

override init(frame: CGRect) {
    super.init(frame: frame)
    commonInit()
}

func commonInit() {
    guard let view = loadViewFromNib() else { return }
    view.frame = self.bounds
    self.addSubview(view)
    contentView = view
}

func loadViewFromNib() -> UIView? {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: nibName, bundle: bundle)
    return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}

By putting designable keyword before class name will make this view to be used in storyboard way you want(by putting custom view class name in identity inspector.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...