问题
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.
回答1:
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.
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.
来源:https://stackoverflow.com/questions/48739735/reloading-view-after-applying-scale-transform-breaks-frame-of-the-uiscrollview-i