0

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

当我从图像中删除.flexibleHeight选项时autoresizingMaskhostedView图像不再显示。这是为什么?我怎样才能得到我想要的行为?

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
    }
  }
}
4

1 回答 1

0

这是在纯 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
                            }
                    )
            }
        }
    }
}
于 2021-10-03T08:18:40.273 回答