
[英]Content inside VStack shrinks when embedded inside a ScrollView in SwiftUI
[英]Add marker over an image that is embedded inside a scrollview in swiftui
与地图上的标记不同,我试图在嵌入在滚动视图中的图像上添加标记(用于缩放和平移)。 我正在使用 UIViewRepresentable 来实现滚动功能和点击手势功能。 想了解如何添加标记。 PFB我的代码
import Foundation
import SwiftUI
struct ZoomableView: UIViewRepresentable {
let uiImage: UIImage
let viewSize: CGSize
var tappedCallback: ((CGPoint) -> Void)
private enum Constraint: String {
case top
case leading
}
private var minimumZoomScale: CGFloat {
let widthScale = viewSize.width / uiImage.size.width
let heightScale = viewSize.height / uiImage.size.height
return min(widthScale, heightScale)
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator
scrollView.maximumZoomScale = minimumZoomScale * 50
scrollView.minimumZoomScale = minimumZoomScale
scrollView.bouncesZoom = true
let gesture = UITapGestureRecognizer(target: context.coordinator,
action: #selector(Coordinator.tapped))
gesture.numberOfTapsRequired = 2
let imageView = UIImageView(image: uiImage)
imageView.addGestureRecognizer(gesture)
imageView.isUserInteractionEnabled = true
scrollView.addSubview(imageView)
imageView.translatesAutoresizingMaskIntoConstraints = false
let topConstraint = imageView.topAnchor.constraint(equalTo: scrollView.topAnchor)
topConstraint.identifier = Constraint.top.rawValue
topConstraint.isActive = true
let leadingConstraint = imageView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor)
leadingConstraint.identifier = Constraint.leading.rawValue
leadingConstraint.isActive = true
imageView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
return scrollView
}
func makeCoordinator() -> Coordinator {
return Coordinator(tappedCallback:self.tappedCallback)
}
func updateUIView(_ scrollView: UIScrollView, context: Context) {
guard let imageView = scrollView.subviews.first as? UIImageView else {
return
}
// Inject dependencies into coordinator
context.coordinator.zoomableView = imageView
context.coordinator.imageSize = uiImage.size
context.coordinator.viewSize = viewSize
let topConstraint = scrollView.constraints.first { $0.identifier == Constraint.top.rawValue }
let leadingConstraint = scrollView.constraints.first { $0.identifier == Constraint.leading.rawValue }
context.coordinator.topConstraint = topConstraint
context.coordinator.leadingConstraint = leadingConstraint
// Set initial zoom scale
scrollView.zoomScale = minimumZoomScale
}
}
// MARK: - Coordinator
extension ZoomableView {
class Coordinator: NSObject, UIScrollViewDelegate {
var zoomableView: UIView?
var imageSize: CGSize?
var viewSize: CGSize?
var topConstraint: NSLayoutConstraint?
var leadingConstraint: NSLayoutConstraint?
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
zoomableView
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let zoomScale = scrollView.zoomScale
print("zoomScale = \(zoomScale)")
print("offset = \(scrollView.contentOffset)")
print("Content size \(scrollView.contentSize)")
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
let zoomScale = scrollView.zoomScale
print("zoomScale = \(zoomScale)")
print("offset = \(scrollView.contentOffset)")
print("Content size \(scrollView.contentSize)")
guard
let topConstraint = topConstraint,
let leadingConstraint = leadingConstraint,
let imageSize = imageSize,
let viewSize = viewSize
else {
return
}
topConstraint.constant = max((viewSize.height - (imageSize.height * zoomScale)) / 2.0, 0.0)
leadingConstraint.constant = max((viewSize.width - (imageSize.width * zoomScale)) / 2.0, 0.0)
}
var tappedCallback: ((CGPoint) -> Void)
init(tappedCallback: @escaping ((CGPoint) -> Void)) {
self.tappedCallback = tappedCallback
}
@objc func tapped(gesture:UITapGestureRecognizer) {
let point = gesture.location(in: gesture.view)
self.tappedCallback(point)
}
}
}
双击时,我想在那一点上放一个标记
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.