IBInspectable变量值在接口构建器和模拟器中未更改

时间:2019-02-04 06:02:02

标签: swift uiview ibinspectable

我正在创建自定义平行四边形视图,并且该视图使用默认偏移值呈现良好。但是,当我从ib更改偏移量值时,它不起作用

@IBDesignable class CustomParallelogramView: UIView {


    @IBInspectable var offset: Float = 10.0

    var path = UIBezierPath()

    lazy var shapeLayer: CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.path = path.cgPath
        return layer
    }()

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

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

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        drawParallelogram()
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        updateFrame()
    }



    func drawParallelogram() {
        print(offset)
        path.move(to: CGPoint(x: bounds.minX + CGFloat(offset), y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX - CGFloat(offset), y: bounds.maxY))
        path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
        path.close()
        self.layer.mask = shapeLayer

    }

    func updateFrame() {
        shapeLayer.frame = bounds
    }

}

我从IB更改了偏移值,但没有更改IB和模拟器

2 个答案:

答案 0 :(得分:2)

尝试:

@IBInspectable var offset: Float = 10.0 {
    didSet {
        drawParallelogram()
    }
}

答案 1 :(得分:2)

一些想法:

  1. 正如丹尼尔所说,您确实想在您的drawParallelgram观察者中调用offset

  2. 此外,您正在layoutSubviews中更新形状图层的frame。您想重置其path并再次更新您的遮罩。

  3. 您正在向UIBezierPath添加越来越多的笔画。您可能只想使其成为局部变量,并避免向现有路径中添加越来越多的笔画。

  4. prepareForInterfaceBuilder对这种方法的目的提出了一些误解。从IB启动时,这不是为了进行初始化。除了IB要求的init方法已经完成的功能之外,这是为了进行一些特殊的配置。

    例如如果您有一个复杂的图表视图,以后将通过编程方式以编程方式提供实际图表数据,但是仍然希望在IB中看到某些内容,例如,您可能prepareForInterfaceBuilder填充了一些虚拟数据。但您不应重复在init方法中已经进行的配置。

  5. 这与这里无关(因为我将建议您摆脱这些init方法),但是对于它的价值,如果我需要在init期间进行配置,通常编写两个init方法:

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
    
        <#call configure routine here#>
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    
        <#call configure routine here#>
    }
    

    请注意,在init(frame:)中,我还提供了默认值.zero。这样可以确保我在所有三种情况下都能得到满足:

    • CustomView()
    • CustomView(frame:);或
    • 如果情节提要调用CustomView(decoder:)

    简而言之,我以两种价格获得了三种init方法。大声笑。


话虽如此,您可以大大简化:

@IBDesignable public class CustomParallelogramView: UIView {

    @IBInspectable public var offset: CGFloat = 10 { didSet { updateMask() } }

    override public func layoutSubviews() {
        super.layoutSubviews()
        updateMask()
    }

    private func updateMask() {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
        path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
        path.close()

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        layer.mask = shapeLayer
    }
}