Want to perform operation BitwiseAND(UIImage1, UIImage2) this is function of OpenCV framework. UIImage1 is already presented in MainVC:
@IBOutlet weak var presentedImage: UIImageView!
So, UIImage2 must be picked additionally, whenever user wants it. Worth to mention :
@IBOutlet weak var presentedImage: UIImageView!
is also picked with the same PHPicker, as UIImage2
Created 2 flags:
@IBOutlet weak var presentedImage: UIImageView!
or for "Bitwise's purpose".
This is the flag:
private var isBitwisePick: Bool = false
private var bitwiseOperationType: OperationTypes.ControllerTypes.BitwiseTypes?
enum ControllerTypes{
/*...*/
enum BitwiseTypes{ case AND,NOR,XOR,OR }
/*.../
}
/* This is switch-case of callback from other viewcontroller.
In our case only this one matters
*/
case .BITWISE_VC(let bitwise):
self.isBitwisePick = true //Pick image for "Bitwise purpose"
self.bitwiseOperationType = bitwise // determines type of Bitwise
// config and present PHPicker
var config = PHPickerConfiguration()
config.filter = .images
config.selectionLimit = 1
let picker = PHPickerViewController(configuration: config)
picker.delegate = self
self.present(picker, animated: true)
extension MainViewController: PHPickerViewControllerDelegate{
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true)
print("test before async \(self.isBitwisePick)")
if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self){
let previousImage = self.presentedImage.image
itemProvider.loadObject(ofClass: UIImage.self){ [weak self] image, error in
DispatchQueue.main.async { [self] in
guard let self = self, let image = image as? UIImage, self.presentedImage.image == previousImage else {
return
}
print("Im in async \(self.isBitwisePick)")
if(self.isBitwisePick){
switch self.bitwiseOperationType{
case .AND:
self.presentedImage.image = OpenCVWrapper.bitwiseAND(self.presentedImage.image, with: image)
break
default:
print("the same for XOR OR NOR")
break
}
}
else{ self.presentedImage.image = image }
}
}
self.isBitwisePick = false
}
}
}
With the line
print(" test before async (self.isBitwisePick)")
I can see, that flag changed and its value is true
However... The line:
print("Im in async (self.isBitwisePick)") prints value : false
I've just started with swift, read some posts and docs about solutions like DispatchQueue or DispatchGroup... But i couldn't fix it out. That's why I'm asking for your help and tips. Thank You for your time :)
The problem is the line
self.isBitwisePick = false
In your didFinishPicking()
function. That line will execute before the completion handler of your itemProvider.loadObject(ofClass:)
function is called. Then when you check isBitwisePick in your completion handler, it will be false. You should move that line inside your completion handler.
Matic Oblak's suggestion about saving the first image and the second image into your data model is good. The way you take the original image out of the image view doesn't seem right, since after a bitwise operation, the image view will contain a processed image, won't it? (Plus, in general terms, you shouldn't store data in view objects. View objects are for displaying info to the user and collecting input from the user, not storing data. That's what a model is for. (I suggest you read up on the MVC design pattern. There are lots of other alternative design patterns, but like MVC, pretty much all of them have you not treat views as a place to store data.)