Значение переменной IBInspectable не изменяется в конструкторе интерфейса и симуляторе - PullRequest
0 голосов
/ 04 февраля 2019

Я создаю пользовательский вид параллелограмма, и вид отображается нормально со значением смещения по умолчанию.Но когда я изменяю значение смещения с 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 голосов
/ 04 февраля 2019

Пара мыслей:

  1. Как сказал Даниил, вы действительно хотите позвонить drawParallelgram своему offset наблюдателю.

  2. Кроме того, в layoutSubviews вы обновляете frame вашего слоя формы.Вы хотите сбросить path и снова обновить маску.

  3. Вы просто добавляете все больше и больше штрихов к своему UIBezierPath.Вы, вероятно, просто хотите сделать его локальной переменной и избегать добавления все большего количества штрихов к существующему пути.

  4. prepareForInterfaceBuilder предлагает некоторое неправильное представление о цели этого метода.Это не для инициализации при запуске из IB.Это сделано для того, чтобы выполнить какую-то специальную настройку, помимо того, что уже сделано методами init, требуемыми IB.

    Например, если у вас есть сложное представление диаграммы, где вы будете программно предоставлять реальные данные диаграммыпрограммно позже, но вы хотели увидеть что-то в 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 метода по цене двух.Lol.


Все сказанное, вы можете значительно упростить это:

@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
    }
}
0 голосов
/ 04 февраля 2019

Попробуйте:

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