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