如何在SwiftUI 2.0滚动视图中保存完成的图像';已由用户调整大小并重新定位

如何在SwiftUI 2.0滚动视图中保存完成的图像';已由用户调整大小并重新定位,swiftui,Swiftui,使用Swift 2.0,我希望找到一种方法,在用户从滚动视图(ZoomScrollView)中选择希望在帧中看到的方式后,捕获调整大小的图像 我知道Swift中有很多复杂的例子,但我希望能找到一种更简单的方法在Swift 2.0中实现这一点。在我所有的搜索中,我都听到过关于使用ZStack和一些遮罩或覆盖层的引用,但找不到一个简单的好例子 我希望有人能更新我的例子与ZStack,面具等,以及如何提取图像保存或提供一个更好的例子 import SwiftUI struct ContentView

使用Swift 2.0,我希望找到一种方法,在用户从滚动视图(ZoomScrollView)中选择希望在帧中看到的方式后,捕获调整大小的图像

我知道Swift中有很多复杂的例子,但我希望能找到一种更简单的方法在Swift 2.0中实现这一点。在我所有的搜索中,我都听到过关于使用ZStack和一些遮罩或覆盖层的引用,但找不到一个简单的好例子

我希望有人能更新我的例子与ZStack,面具等,以及如何提取图像保存或提供一个更好的例子

import SwiftUI

struct ContentView: View {
    @Environment(\.presentationMode) var presentationMode

    @State var isAccepted: Bool = false
    
    @State var isShowingImagePicker = false
    @State var isShowingActionPicker = false
    
    @State var sourceType:UIImagePickerController.SourceType = .camera
    @State var image:UIImage?
    
    var body: some View {
        HStack {
            Color(UIColor.systemYellow).frame(width: 8)
            VStack(alignment: .leading) {
                HStack {
                    Spacer()
                    VStack {
                        if image != nil {
                            ZoomScrollView {
                              Image(uiImage: image!)
                                .resizable()
                                .scaledToFit()
                            }
                            .frame(width: 300, height: 300, alignment: .center)
                            .clipShape(Circle())
                            
                        } else {
                            Image(systemName: "person.crop.circle")
                                .resizable()
                                .font(.system(size: 32, weight: .light))
                                .frame(width: 300, height: 300, alignment: .center)
                                .cornerRadius(180)
                                .foregroundColor(Color(.systemGray))
                                .clipShape(Circle())
                                
                        }
                    }
                    Spacer()
                }
                Spacer()
                
                HStack {
                    Button(action: {
                        self.isShowingActionPicker = true
                    }, label: {
                        Text("Select Image")
                            .foregroundColor(.blue)
                    })
                    .frame(width: 130)
                    .actionSheet(isPresented: $isShowingActionPicker, content: {
                        ActionSheet(title: Text("Select a profile avatar picture"), message: nil, buttons: [
                            .default(Text("Camera"), action: {
                                self.isShowingImagePicker = true
                                self.sourceType = .camera
                            }),
                            .default(Text("Photo Library"), action: {
                                self.isShowingImagePicker = true
                                self.sourceType = .photoLibrary
                            }),
                            .cancel()
                        ])
                    })
                    .sheet(isPresented: $isShowingImagePicker) {
                        imagePicker(image: $image, isShowingImagePicker: $isShowingImagePicker ,sourceType: self.sourceType)
                    }
                    
                    Spacer()
                    
                    // Save button
                    Button(action: {

                        // Save Image here...  print for now just see if file dimensions are the right size
                        print("saved: ", image!)
                        self.presentationMode.wrappedValue.dismiss()
                    }
                    ) {
                        HStack {
                            Text("Save").foregroundColor(isAccepted ? .gray : .blue)
                        }
                    }
                    .frame(width: 102)
                    .padding(.top)
                    .padding(.bottom)
                    //.buttonStyle(RoundedCorners())
                    .disabled(isAccepted)  // Disable if if already isAccepted is true
                }
            }
            Spacer()
            Color(UIColor.systemYellow).frame(width: 8)
        }
        .padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
        .background(Color(UIColor.systemYellow))
    }
}

struct ZoomScrollView<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
    }
  }
}

struct imagePicker:UIViewControllerRepresentable {
    @Binding var image: UIImage?
    @Binding var isShowingImagePicker: Bool
    
    typealias UIViewControllerType = UIImagePickerController
    typealias Coordinator = imagePickerCoordinator
    
    var sourceType:UIImagePickerController.SourceType = .camera
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator
        return picker
    }
    
    func makeCoordinator() -> imagePickerCoordinator {
        return imagePickerCoordinator(image: $image, isShowingImagePicker: $isShowingImagePicker)
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}

class imagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    @Binding var image: UIImage?
    @Binding var isShowingImagePicker: Bool
    
    init(image:Binding<UIImage?>, isShowingImagePicker: Binding<Bool>) {
        _image = image
        _isShowingImagePicker = isShowingImagePicker
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let uiimage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            image = uiimage
            isShowingImagePicker = false
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        isShowingImagePicker = false
    }
}

导入快捷界面
结构ContentView:View{
@环境(\.presentationMode)变量presentationMode
@已接受状态变量:Bool=false
@状态变量isShowingImagePicker=false
@状态变量isShowingActionPicker=false
@状态变量sourceType:UIImagePickerController.sourceType=.camera
@状态变量映像:UIImage?
var body:一些观点{
HStack{
颜色(UIColor.systemYellow)。边框(宽度:8)
VStack(对齐:。前导){
HStack{
垫片()
VStack{
如果图像!=nil{
ZoomScrollView{
图像(uiImage:Image!)
.可调整大小()
.scaledofit()
}
.框架(宽度:300,高度:300,对齐:。中心)
.clipShape(圆())
}否则{
图像(系统名称:“person.crop.circle”)
.可调整大小()
.font(.system(大小:32,重量:轻))
.框架(宽度:300,高度:300,对齐:。中心)
.转弯半径(180)
.foregroundColor(颜色(.systemGray))
.clipShape(圆())
}
}
垫片()
}
垫片()
HStack{
按钮(操作:{
self.isShowingActionPicker=true
},标签:{
文本(“选择图像”)
.foregroundColor(.blue)
})
.框架(宽度:130)
.actionSheet(显示:$isShowingActionPicker,内容:{
操作表(标题:文本(“选择个人资料头像图片”),消息:无,按钮:[
.默认值(文本(“摄影机”),操作:{
self.isShowingImagePicker=true
self.sourceType=.camera
}),
.default(文本(“照片库”),操作:{
self.isShowingImagePicker=true
self.sourceType=.photoLibrary
}),
.取消
])
})
.sheet(显示:$isShowingImagePicker){
imagePicker(image:$image,isShowingImagePicker:$isShowingImagePicker,sourceType:self.sourceType)
}
垫片()
//保存按钮
按钮(操作:{
//在此处保存图像…现在打印,看看文件尺寸是否正确
打印(“已保存:”,图像!)
self.presentationMode.wrappedValue.discouse()文件
}
) {
HStack{
文本(“保存”).foregroundColor(已接受?.gray:.蓝色)
}
}
.框架(宽度:102)
.padding(.top)
.padding(.bottom)
//.Button样式(圆角()
.disabled(isAccepted)//如果已isAccepted为true,则禁用
}
}
垫片()
颜色(UIColor.systemYellow)。边框(宽度:8)
}
.padding(.top,UIApplication.shared.windows.first?.safeAreaInsets.top)
.背景(颜色(UIColor.systemYellow))
}
}
结构ZoomScrollView:UIViewRepresentable{
私有var内容:内容
init(@ViewBuilder内容:()->content){
self.content=content()
}
func makeUIView(上下文:context)->UIScrollView{
//设置UIScrollView
让scrollView=UIScrollView()
scrollView.delegate=context.coordinator//for viewForZooming(in:)
scrollView.maximumZoomScale=20
scrollView.minimumZoomScale=1
scrollView.bouncesZoom=true
//创建一个UIHostingController来保存我们的SwiftUI内容
让hostedView=context.coordinator.hostingController.view!
hostedView.translatesAutoresizingMaskIntoConstraints=true
hostedView.autoresizingMask=[.flexibleWidth、.flexibleHeight]
hostedView.frame=scrollView.bounds
scrollView.addSubview(hostedView)
返回滚动视图
}
func makeCoordinator()->Coordinator{
返回协调器(hostingController:UIHostingController(rootView:self.content))
}
func updateUIView(uiView:UIScrollView,context:context){
//更新主机控制器的SwiftUI内容
context.coordinator.hostingController.rootView=self.content
断言(context.coordinator.hostingController.view.superview==uiView)
}
//马克:协调员
类协调器:NSObject、UIScrollViewDelegate{
var hostingControll
    @State private var rect: CGRect = .zero
    @State private var uiimage: UIImage? = nil  // resized image
                        if image != nil {
                            ZoomScrollView {
                                Image(uiImage: image!)
                                    .resizable()
                                    .scaledToFit()
                            }
                            .frame(width: 300, height: 300, alignment: .center)
                            .clipShape(Circle())
                            .background(RectGetter(rect: $rect))  
extension UIView {
    func asImage(rect: CGRect) -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: rect)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

struct RectGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { proxy in
            self.createView(proxy: proxy)
        }
    }

    func createView(proxy: GeometryProxy) -> some View {
        DispatchQueue.main.async {
            self.rect = proxy.frame(in: .global)
        }

        return Rectangle().fill(Color.clear)
    }
}
                        self.uiimage = UIApplication.shared.windows[0].rootViewController?.view.asImage(rect: self.rect)
self.uiimage = UIApplication.shared.windows[0].self.asImage(rect: self.rect)