Просмотр розыгрыша с помощью IBDesignable + UIView (раскадровка), но не отображается в приложении

Я пытаюсь нарисовать пунктирные линии в приложении, но оно рисует только main.storyboard с помощью IBDesignable. Когда я запускаю приложение на симуляторе iOS, ничего не отображается. Что творится?

введите здесь описание изображения

Код для рисования:

    @IBDesignable
    class AnalogView: UIView {



        fileprivate let thickHorizontalLayer = CAShapeLayer()
        fileprivate let thinHorizontalLayer = CAShapeLayer()

        @IBInspectable var thickYCoord = 50.0
        @IBInspectable var thinYCoord = 52.5

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

            let thickDashesPath = UIBezierPath()
            thickDashesPath.move(to: CGPoint(x: 0, y: thickYCoord)) //left

            thickDashesPath.addLine(to: CGPoint(x: 340, y: thickYCoord)) //right

            //thickHorizontalLayer.frame           = frame
            thickHorizontalLayer.path            = thickDashesPath.cgPath
            thickHorizontalLayer.strokeColor     = UIColor.black.cgColor //dashes color
            thickHorizontalLayer.lineWidth       = 20
            thickHorizontalLayer.lineDashPattern = [ 1, 83.5 ]
            //thickHorizontalLayer.lineDashPhase   = 0.25

            self.layer.addSublayer(thickHorizontalLayer)

            let thinDashesPath = UIBezierPath()
            thinDashesPath.move(to: CGPoint(x: 0, y: thinYCoord)) //esquerda
            thinDashesPath.addLine(to: CGPoint(x: 340, y: thinYCoord)) //direita

            //thinHorizontalLayer.frame            = frame
            thinHorizontalLayer.path             = thinDashesPath.cgPath
            thinHorizontalLayer.strokeColor      = UIColor.black.cgColor
            thinHorizontalLayer.lineWidth        = 15.0
            thinHorizontalLayer.fillColor        = UIColor.clear.cgColor
            thinHorizontalLayer.lineDashPattern  = [ 0.5, 7.95]
            //thinHorizontalLayer.lineDashPhase    = 0.25

            self.layer.addSublayer(thinHorizontalLayer)

person denisb411    schedule 21.03.2017    source источник
comment
Где ваша init(coder:) реализация?   -  person jlehr    schedule 22.03.2017


Ответы (1)


Вам нужно поместить общий код в процедуру, которая вызывается как init(frame:), так и init(coder:):

@IBDesignable
class AnalogView: UIView {

    fileprivate let thickHorizontalLayer = CAShapeLayer()
    fileprivate let thinHorizontalLayer = CAShapeLayer()

    @IBInspectable var thickYCoord: CGFloat = 50.0
    @IBInspectable var thinYCoord: CGFloat = 52.5

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)

        configure()
    }

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

        configure()
    }

    private func configure() {
        let thickDashesPath = UIBezierPath()
        thickDashesPath.move(to: CGPoint(x: 0, y: thickYCoord)) //left
        thickDashesPath.addLine(to: CGPoint(x: 340, y: thickYCoord)) //right

        thickHorizontalLayer.path            = thickDashesPath.cgPath
        thickHorizontalLayer.strokeColor     = UIColor.black.cgColor //dashes color
        thickHorizontalLayer.lineWidth       = 20
        thickHorizontalLayer.lineDashPattern = [ 1, 83.5 ]

        self.layer.addSublayer(thickHorizontalLayer)

        let thinDashesPath = UIBezierPath()
        thinDashesPath.move(to: CGPoint(x: 0, y: thinYCoord)) //esquerda
        thinDashesPath.addLine(to: CGPoint(x: 340, y: thinYCoord)) //direita

        thinHorizontalLayer.path             = thinDashesPath.cgPath
        thinHorizontalLayer.strokeColor      = UIColor.black.cgColor
        thinHorizontalLayer.lineWidth        = 15.0
        thinHorizontalLayer.fillColor        = UIColor.clear.cgColor
        thinHorizontalLayer.lineDashPattern  = [ 0.5, 7.95]

        self.layer.addSublayer(thinHorizontalLayer)
    }
}

Я также предлагаю объявить явный тип для ваших @IBInspectable типов, иначе вы не сможете настроить их в IB.


Лично, вместо того, чтобы жестко указывать ширину пути, я бы обновил ее при изменении макета. Кроме того, если вы собираетесь сделать эти свойства @IBDesignable, вы действительно захотите обновить пути, если они изменятся.

@IBDesignable
class AnalogView: UIView {

    fileprivate let thickHorizontalLayer = CAShapeLayer()
    fileprivate let thinHorizontalLayer = CAShapeLayer()

    @IBInspectable var thickYCoord: CGFloat = 50.0 { didSet { updatePaths() } }
    @IBInspectable var thinYCoord:  CGFloat = 52.5 { didSet { updatePaths() } }

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)

        configure()
    }

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

        configure()
    }

    private func configure() {
        layer.addSublayer(thickHorizontalLayer)
        layer.addSublayer(thinHorizontalLayer)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePaths()
    }

    private func updatePaths() {
        let thickDashesPath = UIBezierPath()
        thickDashesPath.move(to: CGPoint(x: bounds.origin.x, y: thickYCoord)) //left
        thickDashesPath.addLine(to: CGPoint(x: bounds.origin.x + bounds.size.width, y: thickYCoord)) //right

        thickHorizontalLayer.path            = thickDashesPath.cgPath
        thickHorizontalLayer.strokeColor     = UIColor.black.cgColor //dashes color
        thickHorizontalLayer.lineWidth       = 20
        thickHorizontalLayer.lineDashPattern = [1.0, NSNumber(value: Double(bounds.size.width - 1) / 4 - 1.0) ]

        let thinDashesPath = UIBezierPath()
        thinDashesPath.move(to: CGPoint(x: bounds.origin.x, y: thinYCoord)) //esquerda
        thinDashesPath.addLine(to: CGPoint(x: bounds.origin.x + bounds.size.width, y: thinYCoord)) //direita

        thinHorizontalLayer.path             = thinDashesPath.cgPath
        thinHorizontalLayer.strokeColor      = UIColor.black.cgColor
        thinHorizontalLayer.lineWidth        = 15.0
        thinHorizontalLayer.fillColor        = UIColor.clear.cgColor
        thinHorizontalLayer.lineDashPattern  = [0.5, NSNumber(value: Double(bounds.size.width - 1) / 40 - 0.5)]
    }
}

Возможно, вы захотите отрегулировать штрих, чтобы охватить ширину (я не уверен, нужен ли вам постоянный масштаб или он должен охватывать ширину). Но, надеюсь, это иллюстрирует идею.

person Rob    schedule 21.03.2017
comment
Спасибо за ваше предложение @Rob. Мне нужно избавиться от жестко запрограммированных значений. - person denisb411; 22.03.2017