SwiftUI/UIKit:水平滚动视图缩放视图

Posted

技术标签:

【中文标题】SwiftUI/UIKit:水平滚动视图缩放视图【英文标题】:SwiftUI/UIKit: Horizontal ScrollView to scale view 【发布时间】:2021-10-03 06:26:22 【问题描述】:

我正在尝试使用UIScrollView 水平缩放视图。 我的代码几乎给了我想要的东西,除了它还垂直缩放视图。 我想要实现的是图像只在水平方向上缩放,ScrollView 负责水平滚动。

当我从hostedViewautoresizingMask 中删除.flexibleHeight 选项时,图像不再显示。这是为什么?如何获得我想要的行为?

struct ContentView: View 

    var body: some View 
        ZoomableScrollView 
            Image(systemName: "star")
                .resizable()
                .scaledToFit()
          
    


struct ZoomableScrollView<Content: View>: UIViewRepresentable 
  private var content: Content

  init(@ViewBuilder content: () -> Content) 
    self.content = content()
  

  func makeUIView(context: Context) -> UIScrollView 
    // set up the UIScrollView
    let scrollView = UIScrollView()
    scrollView.delegate = context.coordinator  // for viewForZooming(in:)
    scrollView.maximumZoomScale = 20
    scrollView.minimumZoomScale = 1
    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))
  

  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>

    init(hostingController: UIHostingController<Content>) 
      self.hostingController = hostingController
    

    func viewForZooming(in scrollView: UIScrollView) -> UIView? 
      return hostingController.view
    
  

【问题讨论】:

【参考方案1】:

这是在纯 SwiftUI 中完成的:

struct HorizontalScaleView<Content: View>: View 

    @ViewBuilder var content: Content

    @State private var currentAmount: CGFloat = 0
    @State private var finalAmount: CGFloat = 1

    var body: some View 
        GeometryReader  geo in
            ScrollView(.horizontal) 
                content
                    .scaledToFit()
                    .scaleEffect(x: finalAmount + currentAmount, y: 1)
                    .frame(width: (finalAmount + currentAmount) * geo.size.width, height: geo.size.width)
                    .gesture(
                        MagnificationGesture()
                            .onChanged  amount in
                                self.currentAmount = amount - 1
                            
                            .onEnded  _ in
                                if self.finalAmount + self.currentAmount >= 1 
                                    self.finalAmount += self.currentAmount
                                 else 
                                    self.finalAmount = 1
                                
                                self.currentAmount = 0
                            
                    )
            
        
    

【讨论】:

以上是关于SwiftUI/UIKit:水平滚动视图缩放视图的主要内容,如果未能解决你的问题,请参考以下文章

水平和垂直回收器视图中的滚动问题

具有水平缩放的 UIScrollView - 在子视图中绘制的贝塞尔路径模糊

滚动视图中的 Swift 弹出框

如何在 iOS 上制作垂直滚动视图?

在可缩放的滚动视图中禁用图像视图缩放

如何一键同时控制两个 UIScrollView?