【问题标题】:Subclass UIImageView layoutSubviews() vs. init()子类 UIImageView layoutSubviews() 与 init()
【发布时间】:2020-01-16 22:38:28
【问题描述】:

我发现了一个问题,即重复调用 layoutSubviews(),我在其中创建了(UIImageView 的)子视图并附加了必要的动画,导致动画不断重复而无法停止它们。因此,有必要寻找另一种方式来实现子视图的创建和动画的附加。

显而易见的做法是移动 layoutSubviews() 代码

    override func layoutSubviews() {
        super.layoutSubviews()
        print("layoutSubviews()")
        spindleLeft = addSpindle(index: 1, posX: 505, posY: 350)
        spindleRight = addSpindle(index: 2, posX: 1610, posY: 350)

        spinSpindle(spindle: spindleLeft)
        spinSpindle(spindle: spindleRight)
    }

到初始化

    init(cassetteType: CassetteType) {
        self.cassetteType = cassetteType
        super.init(image: UIImage(named: self.cassetteType.rawValue + "Cassette"))
        self.translatesAutoresizingMaskIntoConstraints = false
        self.isUserInteractionEnabled = true
        self.contentMode = .scaleAspectFit

        print("init(cassetteType:)")

        spindleLeft = addSpindle(index: 1, posX: 505, posY: 350)
        spindleRight = addSpindle(index: 2, posX: 1610, posY: 350)

        spinSpindle(spindle: spindleLeft)
        spinSpindle(spindle: spindleRight)
    }

但是,当我这样做时,主轴子视图不再显示。它们似乎确实已创建并应用了动画,但它们不再可见。

为什么会这样? layoutSubviews 和 init 在这方面有何不同?

addSpindle() 代码像这样创建每个子视图:

    func addSpindle(index: Int, posX: CGFloat, posY: CGFloat) -> UIImageView {
        let cassetteBounds = self.bounds
        let cassetteWidth = cassetteBounds.width
        let cassetteHeight = cassetteBounds.height

        let cassetteImageWidth =  self.image!.size.width
        let cassetteImageHeight = self.image!.size.height

        var scale = cassetteWidth / cassetteImageWidth

        var spindleWidth = cassetteWidth
        var spindleHeight = cassetteImageHeight*scale
        var spindleX = 0 as CGFloat
        var spindleY = (cassetteHeight - spindleHeight)/2

        if spindleHeight > cassetteHeight {
            scale = cassetteHeight / cassetteImageHeight
            spindleHeight = cassetteHeight
            spindleWidth = cassetteImageWidth*scale
            spindleY = 0 as CGFloat
            spindleX = (cassetteWidth - spindleWidth)/2
        }

        let spindle = UIImageView(image: UIImage(named: self.cassetteType.rawValue + "Spindle"))
        self.addSubview(spindle)

        spindle.frame.origin.x = spindleX + (posX*scale)
        spindle.frame.origin.y = spindleY + (posY*scale)
        spindle.frame.size.width = spindle.image!.size.width*scale //299.0
        spindle.frame.size.height = spindle.image!.size.height*scale //299.0

        let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
        gesture.numberOfTouchesRequired = 1
        gesture.minimumPressDuration = 0

        spindle.isUserInteractionEnabled = true
        spindle.isExclusiveTouch = true
        spindle.tag = index
        spindle.addGestureRecognizer(gesture)

        return spindle
    }

【问题讨论】:

    标签: ios uiimageview subview


    【解决方案1】:

    您在 addSpindle 方法中使用了 self.bounds。由于视图尚未在 init 上布局,它的边界尚未确定。

    您可以在 init 上创建主轴视图,但在计算父级边界时,您需要在 layoutSubviews 上设置它们的框架。

    【讨论】:

    • 啊,这正是我一直在寻找的,而且非常有意义。谢谢!
    猜你喜欢
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 2012-07-27
    相关资源
    最近更新 更多