这就是答案。
我添加的有趣的部分是,可以通过绑定属性从外部控制缩放视图的比例。因此,我们不需要仅仅依赖于捏合手势,而是可以添加双击来获得最大比例,返回到正常比例,或者使用滑块(例如)来根据需要更改比例。
我将这段代码的大部分归功于jtbandes对这个问题的回答。
这里,您在单个文件中包含可缩放和可滚动视图的代码以及一个测试视图以显示其工作原理:
`
import SwiftUI
let maxAllowedScale = 4.0
struct TestZoomableScrollView: View {
@State private var scale: CGFloat = 1.0
var doubleTapGesture: some Gesture {
TapGesture(count: 2).onEnded {
if scale < maxAllowedScale / 2 {
scale = maxAllowedScale
} else {
scale = 1.0
}
}
}
var body: some View {
VStack(alignment: .center) {
Spacer()
ZoomableScrollView(scale: $scale) {
Image("foto_producto")
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
.frame(width: 300, height: 300)
.border(.black)
.gesture(doubleTapGesture)
Spacer()
Text("Change the scale")
Slider(value: $scale, in: 0.5...maxAllowedScale + 0.5)
.padding(.horizontal)
Spacer()
}
}
}
struct ZoomableScrollView<Content: View>: UIViewRepresentable {
private var content: Content
@Binding private var scale: CGFloat
init(scale: Binding<CGFloat>, @ViewBuilder content: () -> Content) {
self._scale = scale
self.content = content()
}
func makeUIView(context: Context) -> UIScrollView {
// set up the UIScrollView
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator // for viewForZooming(in:)
scrollView.maximumZoomScale = maxAllowedScale
scrollView.minimumZoomScale = 1
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.bouncesZoom = true
// Create a UIHostingController to hold our SwiftUI content
let hostedView = context.coordinator.hostingController.view!
hostedView.translatesAutoresizingMaskIntoConstraints = true
hostedView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hostedView.frame = scrollView.bounds
scrollView.addSubview(hostedView)
return scrollView
}
func makeCoordinator() -> Coordinator {
return Coordinator(hostingController: UIHostingController(rootView: self.content), scale: $scale)
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
// update the hosting controller's SwiftUI content
context.coordinator.hostingController.rootView = self.content
uiView.zoomScale = scale
assert(context.coordinator.hostingController.view.superview == uiView)
}
class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>
@Binding var scale: CGFloat
init(hostingController: UIHostingController<Content>, scale: Binding<CGFloat>) {
self.hostingController = hostingController
self._scale = scale
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return hostingController.view
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
self.scale = scale
}
}
}
Run Code Online (Sandbox Code Playgroud)
`
我认为这是获得所需行为的最短、最简单的方法。此外,它工作得非常完美,这是我在此处提供的其他解决方案中找不到的。例如,缩小是平滑的,但如果不使用这种方法,通常会出现不稳定的情况。
滑块具有该范围以显示如何尊重最小值和最大值,在真实应用程序中,范围将为 1...maxAllowedScale。
至于双击,可以根据您的喜好轻松更改其行为。
我附上视频以一次性展示所有内容:
我希望这对任何正在寻找此功能的人有所帮助。
| 归档时间: |
|
| 查看次数: |
2081 次 |
| 最近记录: |