Search code examples
swiftmacoscalayerappkitbounds

CALayer bounds don't change after setting them to a certain value


I am trying to display an image as the content of a CALayer slightly zoomed in by changing its bounds to a bigger size. (This is so that I can pan over it later.) For some reason however setting the bounds does not change them or trigger an animation to do so.

This is the code I use to change the bounds:

self.imageLayer.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)

I have a function to compute the CGRect, but this dummy one leads to exactly the same result of the size not changing.

I have also determined, that while I can't see the size change, if I check the bounds of the layer right after setting it, it correctly has the value I set it to.

The following code is executed after setting the bounds. I couldn't find anything in it, that changes them back.

    self.imageLayer.add(self.generatePanAnimation(), forKey: "pan")

func generatePanAnimation() -> CAAnimation {
    var positionA = CGPoint(x: (self.bounds.width / 2), y: self.bounds.height / 2)
    var positionB = CGPoint(x: (self.bounds.width / 2), y: self.bounds.height / 2)

    positionA = self.generateZoomedPosition()
    positionB = self.generateZoomedPosition()

    let panAnimation = CABasicAnimation(keyPath: "position")
    if self.direction == .AtoB {
        panAnimation.fromValue = positionA
        panAnimation.toValue = positionB
    } else {
        panAnimation.fromValue = positionB
        panAnimation.toValue = positionA
    }
    panAnimation.duration = self.panAndZoomDuration

    self.panAnimation = panAnimation
    return panAnimation
}

func generateZoomedPosition() -> CGPoint {
    let maxRight = self.zoomedImageLayerBounds.width / 2
    let maxLeft = self.bounds.width - (self.zoomedImageLayerBounds.height / 2)
    let maxUp = self.zoomedImageLayerBounds.height / 2
    let maxDown = self.bounds.height - (self.zoomedImageLayerBounds.height / 2)

    let horizontalFactor = CGFloat(arc4random()) / CGFloat(UINT32_MAX)
    let verticalFactor = CGFloat(arc4random()) / CGFloat(UINT32_MAX)

    let randomX = maxLeft + horizontalFactor * (maxRight - maxLeft)
    let randomY = maxDown + verticalFactor * (maxUp - maxDown)

    return CGPoint(x: randomX, y: randomY)
}

I even tried setting the bounds as shown below, but it didn't help.

CATransaction.begin()
CATransaction.setValue(true, forKey: kCATransactionDisableActions)
self.imageLayer.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
CATransaction.commit()

I really hope someone has an idea. Thanks a lot!


Solution

  • The way to change the apparent drawing size of a layer is not to change its bounds but to change its transform. To make the layer look larger, including its drawing, apply a scale transform.