为UiviewRementable ScrollView(SwiftUi)设置ContentOffset
问题
我正在尝试使用给定的缩放和位置启动UiviewSrentable scrollview的
。我在MakeUiview中设置了新的Zoom和新的ContentOffset,但是SetContentOffset调用没有视觉效果,并且在从新的Zoom中重新放大时,ScrollView会移动内容,就好像SetContentOffSet一样效果。
我在做什么错?
下面的代码
是uiviewermesentable的整个代码。我标记了最相关的行,并带有“请参阅此处”评论。
import SwiftUI
struct ZoomableScrollView<Content: View>: UIViewRepresentable {
@EnvironmentObject var drawingModel: DrawingModel
private var content: Content
let screenScale: CGFloat
init(screenScale: CGFloat, @ViewBuilder content: () -> Content) {
self.screenScale = screenScale
self.content = content()
}
func makeUIView(context: Context) -> UIScrollView {
// set up the UIScrollView
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator // for viewForZooming(in:)
let fullPageZoomScale = 0.85 * screenScale // screenScale is a constant
scrollView.maximumZoomScale = fullPageZoomScale * 10
scrollView.minimumZoomScale = fullPageZoomScale
scrollView.zoomScale = fullPageZoomScale
scrollView.bouncesZoom = true
scrollView.delaysContentTouches = false
// 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)
/// -------- SEE HERE These two lines does not work as intended
scrollView.setZoomScale(0.5319657829374683, animated: false)
scrollView.setContentOffset(CGPoint(x: 518.5, y: 330.0), animated: false)
/// -----
return scrollView
}
func makeCoordinator() -> Coordinator {
return Coordinator(hostingController: UIHostingController(rootView: self.content),
userScrolledAction: drawingModel.userScrollAction,
userZoomedAction: drawingModel.userZoomAction)
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
// update the hosting controller's SwiftUI content
context.coordinator.hostingController.rootView = self.content
assert(context.coordinator.hostingController.view.superview == uiView)
}
/// MARK: - Coordinator
class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>
let userScrolledAction: (CGPoint) -> Void
let userZoomedAction: (CGFloat) -> Void
init(hostingController: UIHostingController<Content>, userScrolledAction: @escaping (CGPoint) -> Void, userZoomedAction: @escaping (CGFloat) -> Void) {
self.hostingController = hostingController
self.userScrolledAction = userScrolledAction
self.userZoomedAction = userZoomedAction
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return hostingController.view
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
userScrolledAction(scrollView.contentOffset)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
userZoomedAction(scrollView.zoomScale)
}
}
}
Problem
I'm trying to start an UIViewRepresentable ScrollView with a given zoom and position.
I set the new zoom and new contentOffset in the makeUIView, but the setContentOffset call has no VISUAL effect and when zooming back out from the new zoom, the scrollview moves the content as if the setContentOffset had had effect.
What am I doing wrong?
Code
Below is the entire code for the UIViewRepresentable. I've marked the most relevant lines with a 'SEE HERE' comment.
import SwiftUI
struct ZoomableScrollView<Content: View>: UIViewRepresentable {
@EnvironmentObject var drawingModel: DrawingModel
private var content: Content
let screenScale: CGFloat
init(screenScale: CGFloat, @ViewBuilder content: () -> Content) {
self.screenScale = screenScale
self.content = content()
}
func makeUIView(context: Context) -> UIScrollView {
// set up the UIScrollView
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator // for viewForZooming(in:)
let fullPageZoomScale = 0.85 * screenScale // screenScale is a constant
scrollView.maximumZoomScale = fullPageZoomScale * 10
scrollView.minimumZoomScale = fullPageZoomScale
scrollView.zoomScale = fullPageZoomScale
scrollView.bouncesZoom = true
scrollView.delaysContentTouches = false
// 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)
/// -------- SEE HERE These two lines does not work as intended
scrollView.setZoomScale(0.5319657829374683, animated: false)
scrollView.setContentOffset(CGPoint(x: 518.5, y: 330.0), animated: false)
/// -----
return scrollView
}
func makeCoordinator() -> Coordinator {
return Coordinator(hostingController: UIHostingController(rootView: self.content),
userScrolledAction: drawingModel.userScrollAction,
userZoomedAction: drawingModel.userZoomAction)
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
// update the hosting controller's SwiftUI content
context.coordinator.hostingController.rootView = self.content
assert(context.coordinator.hostingController.view.superview == uiView)
}
/// MARK: - Coordinator
class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>
let userScrolledAction: (CGPoint) -> Void
let userZoomedAction: (CGFloat) -> Void
init(hostingController: UIHostingController<Content>, userScrolledAction: @escaping (CGPoint) -> Void, userZoomedAction: @escaping (CGFloat) -> Void) {
self.hostingController = hostingController
self.userScrolledAction = userScrolledAction
self.userZoomedAction = userZoomedAction
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return hostingController.view
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
userScrolledAction(scrollView.contentOffset)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
userZoomedAction(scrollView.zoomScale)
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
应该进入
should move into