使用可选的 IBOutlets 创建 UIView 子类

Creating a UIView subclass with optional IBOutlets

我正在尝试实现一个名为 MediaView 的自定义 UIView。

里面我默认会有一个loading indicator。在它上面,将显示图像、GIF 或视频。那里只会绘制一个 IBOutlet。

我怎样才能做到这一点?

class MediaView: UIView{

@IBOutlet weak var loadingIndicator : LoadingActivityIndicator!

@IBOutlet weak var apngImageView : APNGImageView?
@IBOutlet weak var animatedImageView : AnimatedImageView?
@IBOutlet weak var player : Player?

// MARK: - Initializers

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

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

// MARK: - Private Helper Methods

// Performs the initial setup.
private func setupView() {
    let view = viewFromNibForClass()
    view.frame = bounds

    // Auto-layout stuff.
    view.autoresizingMask = [
        UIViewAutoresizing.FlexibleWidth,
        UIViewAutoresizing.FlexibleHeight
    ]

    // Show the view.
    addSubview(view)
}

// Loads a XIB file into a view and returns this view.
private func viewFromNibForClass() -> UIView {

    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil).first as! UIView

    return view
}

}

如果您真的想从层次结构中删除视图(而不是仅仅隐藏它们),有两种 "straightforward" 方法可以解决这个问题:

  1. 当您告诉您的子类 "init" 本身用于 "image type," 时,只需在您不再需要的两个视图中的每一个上使用 .removeFromSuperview()。只要确保没有任何东西依赖于这些视图(约束、值检查等)。

  1. 不是在 Interface Builder 中添加视图并使用 @IBOutlet 引用它们,而是通过代码仅 添加 所需的对象作为子视图。

顺便说一句,我不确定这两种方法是否一定是 "better" ...方法 1。可能更容易将对象放在您想要的位置(布局和其他属性),但是方法2. 可能会多一点 "light-weight",以后修改起来会更容易。