TimOliver / TOCropViewController

A view controller for iOS that allows users to crop portions of UIImage objects
http://www.timoliver.com.au/2015/06/21/tocropviewcontroller-an-open-source-image-cropper-for-ios/
MIT License
4.67k stars 929 forks source link

SwiftUI example of using TOCropViewController #421

Open ClaesClaes opened 3 years ago

ClaesClaes commented 3 years ago

Hi, are there a SwiftUI example of using TOCropViewController? I've just started to learn SwiftUI and have no previous experiences of UIViewcontroller so would help get me going.

TimOliver commented 3 years ago

Hi @ClaesClaes! Oh wow! Welcome to the Swift community then!

A few people have asked this before. Apple's released a few tutorials that hopefully point in the right direction: https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit

Unfortunately, I don't know a whole lot about SwiftUI (I'm still sticking with UIKit for a little longer. :) ), so I sadly can't commit the time to learning and then writing a sample app at the moment.

I'll leave this issue open with a "PR Requested" status attached. If anyone else would like to make a SwiftUI sample and post a PR for it, that would be super appreciated. :)

I hope that helps!

ClaesClaes commented 3 years ago

Hi Tim, Thank you for your reply. I’ve managed to integrate the TOCropViewController in my SwiftUI project so it (mostly) looks good for now. I can post some code+instructions when time allows. Cheers, Claes

On Jul 20, 2020, at 2:37 PM, Tim Oliver notifications@github.com wrote:

Hi @ClaesClaes https://github.com/ClaesClaes! Oh wow! Welcome to the Swift community then!

A few people have asked this before. Apple's released a few tutorials that hopefully point in the right direction: https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit Unfortunately, I don't know a whole lot about SwiftUI (I'm still sticking with UIKit for a little longer. :) ), so I sadly can't commit the time to learning and then writing a sample app at the moment.

I'll leave this issue open with a "PR Requested" status attached. If anyone else would like to make a SwiftUI sample and post a PR for it, that would be super appreciated. :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/TimOliver/TOCropViewController/issues/421#issuecomment-660858630, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACOX6SWCSSAJWXCJ7KUWH2LR4PX2NANCNFSM4OZHUWVQ.

CH3COOH commented 3 years ago

Hi, @ClaesClaes ! I've created a sample app to use the 'TOCropViewController' with the SwiftUI.

With using SwiftUI, I'm seeing an issue where 'TOCropViewController' can't be closed unless you wait for 1 second when transitioning from 'UIImagePickerController' to 'TOCropViewController'. How have you fixed this problem?

ClaesClaes commented 3 years ago

Hi Kenji, I have not seen such delay in my implementation. I’m not able to test this out this week but can look at it later.

Claes

Sent from my phone. Apologies for brevity & spelling mistakes

On 25 Jul 2020, at 22:12, Kenji Wada notifications@github.com wrote:

 Hi, @ClaesClaes ! I've created a sample app to use the 'TOCropViewController' with the SwiftUI.

https://github.com/CH3COOH/TOCropViewController/tree/issue/421 With using SwiftUI, I'm seeing an issue where 'TOCropViewController' can't be closed unless you wait for 1 second when transitioning from 'UIImagePickerController' to 'TOCropViewController'. How have you fixed this problem?

Xcode 11.6 / iOS 13.6 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

maxtomczyk commented 3 years ago

Hi, I "interfaced" TOCropViewController for SwiftUI. I just started my iOS development adventure, so this code probably is not perfect but it still works and can help some people to start with this repo and SwiftUI.

// FIle: ImageCropper.swift

import SwiftUI
import UIKit
import CropViewController

struct ImageCropper: UIViewControllerRepresentable{
  @Binding var image: UIImage?
  @Binding var visible: Bool
  var done: (UIImage) -> Void

  class Coordinator: NSObject, CropViewControllerDelegate{
    let parent: ImageCropper

    init(_ parent: ImageCropper){
      self.parent = parent
    }

    func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
      withAnimation{
        parent.visible = false
      }
      parent.done(image)
    }

    func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
      withAnimation{
        parent.visible = false
      }
    }
  }

  func makeCoordinator() -> Coordinator {
    return Coordinator(self)
  }

  func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}

  func makeUIViewController(context: Context) -> some UIViewController {
    let img = self.image ?? UIImage()
    let cropViewController = CropViewController(image: img)
    cropViewController.delegate = context.coordinator
    return cropViewController
  }
}

Usage:

// FIle: SomeView.swift
import SwiftUI

struct SomeView: View {
  @State private var showImageCropper = false
  @State private var tempInputImage: UIImage?

  func imageCropped(image: UIImage){
    self.tempInputImage = nil
    self.pictures[self.pickedImageIndex] = Image(uiImage: image)
  }

  var body: some View {
    if showImageCropper {
      ImageCropper(image: self.$tempInputImage, visible: self.$showImageCropper, done: self.imageCropped)
        .zIndex(10)
    }
  }
}
yeyimilk commented 3 years ago

Hi, I "interfaced" TOCropViewController for SwiftUI. I just started my iOS development adventure, so this code probably is not perfect but it still works and can help some people to start with this repo and SwiftUI.

// FIle: ImageCropper.swift

import SwiftUI
import UIKit
import CropViewController

struct ImageCropper: UIViewControllerRepresentable{
  @Binding var image: UIImage?
  @Binding var visible: Bool
  var done: (UIImage) -> Void

  class Coordinator: NSObject, CropViewControllerDelegate{
    let parent: ImageCropper

    init(_ parent: ImageCropper){
      self.parent = parent
    }

    func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
      withAnimation{
        parent.visible = false
      }
      parent.done(image)
    }

    func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
      withAnimation{
        parent.visible = false
      }
    }
  }

  func makeCoordinator() -> Coordinator {
    return Coordinator(self)
  }

  func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}

  func makeUIViewController(context: Context) -> some UIViewController {
    let img = self.image ?? UIImage()
    let cropViewController = CropViewController(image: img)
    cropViewController.delegate = context.coordinator
    return cropViewController
  }
}

Usage:

// FIle: SomeView.swift
import SwiftUI

struct SomeView: View {
  @State private var showImageCropper = false
  @State private var tempInputImage: UIImage?

  func imageCropped(image: UIImage){
    self.tempInputImage = nil
    self.pictures[self.pickedImageIndex] = Image(uiImage: image)
  }

  var body: some View {
    if showImageCropper {
      ImageCropper(image: self.$tempInputImage, visible: self.$showImageCropper, done: self.imageCropped)
        .zIndex(10)
    }
  }
}

func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) { parent.done(image)

    // some how, there maybe a bug, it can not be dismissed except adding this
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        withAnimation{
            self.parent.visible = false
        }
    }
}
chkmls commented 1 year ago

Sorry to reopen it , but the swiftui code return no cropper, and very tiny image. I used the exact code as this

Hi, I "interfaced" TOCropViewController for SwiftUI. I just started my iOS development adventure, so this code probably is not perfect but it still works and can help some people to start with this repo and SwiftUI.

// FIle: ImageCropper.swift

import SwiftUI
import UIKit
import CropViewController

struct ImageCropper: UIViewControllerRepresentable{
  @Binding var image: UIImage?
  @Binding var visible: Bool
  var done: (UIImage) -> Void

  class Coordinator: NSObject, CropViewControllerDelegate{
    let parent: ImageCropper

    init(_ parent: ImageCropper){
      self.parent = parent
    }

    func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
      withAnimation{
        parent.visible = false
      }
      parent.done(image)
    }

    func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
      withAnimation{
        parent.visible = false
      }
    }
  }

  func makeCoordinator() -> Coordinator {
    return Coordinator(self)
  }

  func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {}

  func makeUIViewController(context: Context) -> some UIViewController {
    let img = self.image ?? UIImage()
    let cropViewController = CropViewController(image: img)
    cropViewController.delegate = context.coordinator
    return cropViewController
  }
}

Usage:

// FIle: SomeView.swift
import SwiftUI

struct SomeView: View {
  @State private var showImageCropper = false
  @State private var tempInputImage: UIImage?

  func imageCropped(image: UIImage){
    self.tempInputImage = nil
    self.pictures[self.pickedImageIndex] = Image(uiImage: image)
  }

  var body: some View {
    if showImageCropper {
      ImageCropper(image: self.$tempInputImage, visible: self.$showImageCropper, done: self.imageCropped)
        .zIndex(10)
    }
  }
}

func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) { parent.done(image)

    // some how, there maybe a bug, it can not be dismissed except adding this
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        withAnimation{
            self.parent.visible = false
        }
    }
}