SwiftUI 从几何读取器到函数的传递值

dot*_*ot3 7 swift swiftui

我有一个视图,它使用 Geometry Reader 来计算图像区域应该有多大:

GeometryReader { metrics in
    ZStack{
        self.image
           .resizable()
           .frame(width:  (metrics.size.height - 10) * 0.561403509 , height: metrics.size.height - 10, alignment: .top)
           .clipped()
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我有一个函数,我想使用 GeometryReader 计算的框架高度和宽度来裁剪图像。

我有一个单独的功能,可以在按下按钮时裁剪图像:

 DownloadImageButton(prepareImagefunction: { self.prepareImage() })
Run Code Online (Sandbox Code Playgroud)

然后调用一个 prepareImage 函数:

func prepareImage( ) {
 // In order for image cropping to work, we need the equivalent of view.bounds in order to adjust the crop so that it correctly measures the crop area. We need metrics.width and metrics.height 
 var adjustmentScaleForDisplaySize = targetSize.width / metrics.width
Run Code Online (Sandbox Code Playgroud)

请注意, GeometryReader 是调用 prepareImage 的父视图的子视图。因此,理想情况下,子项会将指标值保存在 EnvironmentObject 或 Binding 中到父项。

Asp*_*eri 9

有没有办法将 GeometryReader 计算的值传递给函数?

是的,你可以这样做。varmetrics是 a GeometryProxy,所以函数签名应该像下面的例子

private func resizedImage(for metrics: GeometryProxy) -> some View {
    self.image
       .resizable()
       .frame(width:  (metrics.size.height - 10) * 0.561403509 , height: metrics.size.height - 10, alignment: .top)
       .clipped()
}
Run Code Online (Sandbox Code Playgroud)

所以你的用法

GeometryReader { metrics in
    ZStack{
       self.resizedImage(for: metrics)
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:对于更改的请求

假设您在子视图中绑定为

@Binding var cropSize: CGSize
Run Code Online (Sandbox Code Playgroud)

上面的函数可以修改如下

private func resizedImage(for metrics: GeometryProxy) -> some View {
    let size = CGSize(width: (metrics.size.height - 10) * 0.561403509, 
                           height: metrics.size.height - 10)
    self.cropSize = size
    return self.image
       .resizable()
       .frame(width: size.width, height: size.height, alignment: .top)
       .clipped()
}
Run Code Online (Sandbox Code Playgroud)