自定义视图不显示通过在情节提要中添加 UIView 继承自自定义 class

Custom View don't show by adding UIView in storyboard to inherit from the customed class

我用 MyCustomView.xib 编写了一个名为 MyCustomView.swift 的自定义视图 class。 当我使用

let customView = MyCustomView(frame:.....)
self.view.addSubView(customView)

将出现自定义视图。

但是当我直接在Storyboard中添加一个UIView,并选择MyCustomView作为自定义Class的class时,它不显示。即使我设置了 UIView 的背景颜色,它也不起作用。特别是当我用@IBDesignable 注释 MyCustomview 时,显示两个错误警告,

Failed to render and update auto layout status fo XXXViewController
Failed to update auto layout status

这是否意味着我应该为情节提要中的自定义视图设置自动布局?

这是MyCustomView.class

import UIKit
@IBDesignable
class MyCustomView:UIView{
@IBOutlet weak var categoryLabel: UILabel!

var category:String = ""{
    didSet{
        self.categoryLabel.text = category
    }
}
var intro:String = ""
var address:String = ""
var distance:CGFloat = 0.0


override init(frame: CGRect) {
    super.init(frame: frame)
    awakeFromNib()
    print("\(#function)")
}
convenience init(){
    print("\(#function)")
    self.init(frame:CGRect.zero)
}

required init?(coder aDecoder: NSCoder) {
    print("\(#function)")
    super.init(coder: aDecoder)
    awakeFromNib()

}

override func awakeFromNib() {
    super.awakeFromNib()
    let view = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as! UIView
    view.autoresizingMask = UIViewAutoresizing.flexibleWidth.union(.flexibleHeight)
    addSubview(view)
}
override func layoutSubviews() {
    super.layoutSubviews()
}

}

尝试删除 @IBDesignable,因为 Xcode 正在寻找 class 中不存在的 IBInspectable 属性

您需要做的是在您的 var 之前添加前缀 @IBInspectable

这里是一个例子:自定义 class: Rainbow.swift

import Foundation
import UIKit

@IBDesignable
class Rainbow: UIView {
    @IBInspectable var firstColor: UIColor = UIColor(red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
    @IBInspectable var secondColor: UIColor = UIColor(red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
    @IBInspectable var thirdColor: UIColor = UIColor(red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    func addOval(_ lineWidth: CGFloat, path: CGPath, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
        
        let arc = CAShapeLayer()
        arc.lineWidth = lineWidth
        arc.path = path
        arc.strokeStart = strokeStart
        arc.strokeEnd = strokeEnd
        arc.strokeColor = strokeColor.cgColor
        arc.fillColor = fillColor.cgColor
        arc.shadowColor = UIColor.black.cgColor
        arc.shadowRadius = shadowRadius
        arc.shadowOpacity = shadowOpacity
        arc.shadowOffset = shadowOffsset
        layer.addSublayer(arc)
    }
    
    override func draw(_ rect: CGRect) {
        // Add ARCs
        self.addCirle(80, capRadius: 20, color: self.firstColor)
        self.addCirle(150, capRadius: 20, color: self.secondColor)
        self.addCirle(215, capRadius: 20, color: self.thirdColor)
    }
    
    func addCirle(_ arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) {
        let X = self.bounds.midX
        let Y = self.bounds.midY
        
        // Bottom Oval
        let pathBottom = UIBezierPath(ovalIn: CGRect(x: (X - (arcRadius/2)), y: (Y - (arcRadius/2)), width: arcRadius, height: arcRadius)).cgPath
        self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clear, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSize.zero)
        
        // Middle Cap
        let pathMiddle = UIBezierPath(ovalIn: CGRect(x: (X - (capRadius/2)) - (arcRadius/2), y: (Y - (capRadius/2)), width: capRadius, height: capRadius)).cgPath
        self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSize.zero)
        
        // Top Oval
        let pathTop = UIBezierPath(ovalIn: CGRect(x: (X - (arcRadius/2)), y: (Y - (arcRadius/2)), width: arcRadius, height: arcRadius)).cgPath
        self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clear, shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSize.zero)
        
    }
}

绘制

来源:https://www.appcoda.com/ibdesignable-ibinspectable-tutorial/

Try add this code :

override func awakeFromNib() {
        super.awakeFromNib()
        xibSetup()
    }

    func xibSetup() {
        guard let view = loadViewFromNib() else { return }
        view.frame = bounds
        view.autoresizingMask = 
                    [.flexibleWidth, .flexibleHeight]
        addSubview(view)
        contentView = view
    }

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