genaks
genaks

Reputation: 757

Reloading view after applying scale transform breaks frame of the UIScrollView inside it

I am using SpreadsheetView and trying to zoom into it using a pinch gesture and a scale transform. The view zooms fine but when I try to reload the data after it has been zoomed out, the frame of the view is much smaller than it should be. This is the snippet of code that handles the zooming of the view -

@IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) {
    if recognizer.state == .began {
        lastScale = Float(recognizer.scale)
    }
    if recognizer.state == .began || recognizer.state == .changed {
        currentScale = recognizer.view?.layer.value(forKeyPath: "transform.scale") as! Float

        var newScale = 1 - (lastScale - Float(recognizer.scale))
        newScale = min(newScale, SpreadsheetViewController.kMaxScale / currentScale)
        newScale = max(newScale, SpreadsheetViewController.kMinScale / currentScale)
        spreadsheetView.transform = spreadsheetView.transform.scaledBy(x: CGFloat(newScale), y: CGFloat(newScale))
        lastScale = Float(recognizer.scale)
    }
    if recognizer.state == .ended {
        spreadsheetView.frame = CGRect(x: 0, y: topView.frame.maxY, width: view.frame.size.width, height: view.frame.size.height - topView.frame.maxY)
        print(spreadsheetView.frame.size.width)
        print(spreadsheetView.scrollView.frame.size.width)
    }
}

I am explicitly setting the frame of the spreadsheetView to cover the frame of the UIViewController after the pinch gesture has ended and it manages to stick to that frame after reloading but I think its the frame of the UIScrollView inside the SpreadsheetView that loses its frame.

Upvotes: 1

Views: 350

Answers (1)

LGP
LGP

Reputation: 4333

The SpreadsheetView seems to use its frame size properties to draw its content. Modifying the transform will change the frame values accordingly, and so using these (instead of the bounds sizes) will make the end result wrong, in your case effectively scaling down twice. This is likely a miss in the SpreadsheetView.

You can work around it by using a container for the SpreadsheetView. Create a regular UIView to do the transforms on, and embed the SpreadsheetView as a child, without any transforms.

I did a quick test on one of the demo apps included with the SpreadsheetView, and it confirms my thoughts. Doing a simple transform directly on the SpreadsheetView with scale 0.5, 0.5, and set the background color to red, results in this picture. Note that the red background is visible, which it shouldn't.

enter image description here

The same test using a UIView as a container for the SpreadsheetView, scaling the container to 0.5, 0.5, and setting the container's background to red, results in this picture. Works as intended.

enter image description here

Upvotes: 1

Related Questions