I have work code like this, it let user pic image from gallery and drag in specific rectangle, the one problem, is save the green frame with picked and moved picture. I have function for screenshot, but I cant make it capture correct. It capture only frame without picked picture. It would be great, if some one can help me with figured this out
import SwiftUI
struct picSelectorFrame:View {
@State var isShowingImagePicker = false
@State var imageInBlackBox = UIImage()
@State var imageSelected = false
@State var imageZIndex = 0.0
@State private var currentPosition: CGSize = .zero
@State private var newPosition: CGSize = .zero
var body: some View{
let picSelector = ZStack{
Image(uiImage: imageInBlackBox)
.resizable()
.scaledToFill()
.background(
Color.gray
.opacity(0.1)
)
.layoutPriority(10)
.zIndex(imageZIndex)
.gesture(DragGesture(minimumDistance: 5)
.onChanged({value in
self.currentPosition = CGSize(width: value.translation.width + self.newPosition.width,
height: value.translation.height + self.newPosition.height)
})
.onEnded({ value in
self.newPosition = self.currentPosition
}))
.offset(self.currentPosition)
Button(action: {
if self.imageSelected == false {
self.isShowingImagePicker.toggle()
self.imageZIndex = 1
self.imageSelected = true
}
}, label: {
Rectangle()
.opacity(0.1)
}
)
.layoutPriority(12)
.sheet(isPresented: $isShowingImagePicker , content: {
ImagePickerViewScreen(isPresented: self.$isShowingImagePicker,
selectedImage: self.$imageInBlackBox)
}
)
}
ZStack{
Rectangle()
.fill( Color(.green))
.opacity(0.3)
.frame(width: 350, height: 350)
picSelector
.frame(width: 300, height: 300)
.mask(
Rectangle()
)
.contentShape(
Rectangle()
)
}
}
}
struct SwiftUIPhotoSelectorScreen: View {
let screenW = UIScreen.main.bounds.width
let screenH = UIScreen.main.bounds.height
var body: some View{
ZStack{
picSelectorFrame()
Button("Save"){
takeScreenshot(origin: CGPoint(x: screenW/2-175, y: screenH/2-175),size:CGSize(width: 350, height: 350))
}
.position(x: screenW/2, y: screenH-50)
}
.edgesIgnoringSafeArea(.all)
}
}
struct ImagePickerViewScreen: UIViewControllerRepresentable {
@Binding var isPresented: Bool
@Binding var selectedImage: UIImage
func makeUIViewController(context:
UIViewControllerRepresentableContext<ImagePickerViewScreen>) ->
UIViewController {
let controller = UIImagePickerController()
controller.delegate = context.coordinator
return controller
}
func makeCoordinator() -> ImagePickerViewScreen.Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
let parent: ImagePickerViewScreen
init(parent: ImagePickerViewScreen) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info:
[UIImagePickerController.InfoKey : Any]) {
if let selectedImageFromPicker = info[.originalImage] as? UIImage {
self.parent.selectedImage = selectedImageFromPicker
}
self.parent.isPresented = false
}
}
func updateUIViewController(_ uiViewController:
ImagePickerViewScreen.UIViewControllerType, context:
UIViewControllerRepresentableContext<ImagePickerViewScreen>) {
}
}
extension View {
func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage {
let window = UIWindow(frame: CGRect(origin: origin, size: size))
let hosting = UIHostingController(rootView: picSelectorFrame())
window.rootViewController = hosting
window.makeKeyAndVisible()
let img = hosting.view.getImage()
UIImageWriteToSavedPhotosAlbum(img, nil ,nil, nil)
return img
}
}
extension UIView {
func getImage() -> UIImage {
let format = UIGraphicsImageRendererFormat()
let renderer = UIGraphicsImageRenderer(size: self.bounds.size, format: format)
let image = renderer.image { rendererContext in
self.layer.render(in: rendererContext.cgContext)
}
return image
}
}
struct SwiftUIPhotoSelectorScreen_Previews: PreviewProvider {
static var previews: some View {
SwiftUIPhotoSelectorScreen()
}
}