[英]Perform action after picking image with async PHPicker
Want to perform operation BitwiseAND(UIImage1, UIImage2) this is function of OpenCV framework .想要执行操作 BitwiseAND(UIImage1, UIImage2)这是 OpenCV 框架的 function 。 UIImage1 is already presented in MainVC:
UIImage1 已经出现在 MainVC 中:
@IBOutlet weak var presentedImage: UIImageView!
So, UIImage2 must be picked additionally, whenever user wants it.因此,用户需要时,必须另外选择 UIImage2。 Worth to mention:
值得一提的是:
@IBOutlet weak var presentedImage: UIImageView!
@IBOutlet 弱变量presentedImage:UIImageView!
is also picked with the same PHPicker, as UIImage2也使用与 UIImage2 相同的 PHPicker
Created 2 flags:创建了 2 个标志:
@IBOutlet weak var presentedImage: UIImageView!
@IBOutlet 弱变量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)")
print(" 异步前测试 (self.isBitwisePick)")
I can see, that flag changed and its value is true我可以看到,该标志已更改,其值为true
However... The line:但是......这条线:
print("Im in async (self.isBitwisePick)") prints value: false
print("Im in async (self.isBitwisePick)") 打印值: 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.我刚刚开始使用 swift,阅读了一些关于 DispatchQueue 或 DispatchGroup 等解决方案的帖子和文档......但我无法解决它。 That's why I'm asking for your help and tips.
这就是为什么我要寻求你的帮助和提示。 Thank You for your time:)
感谢您的时间:)
Your data structure should be something like您的数据结构应该类似于
private var firstImage: UIImage?
private var secondImage: UIImage?
then you can override setters or apply some other mechanism like然后您可以覆盖设置器或应用其他一些机制,例如
private var firstImage: UIImage? { didSet { reevaluateImagesSet() } }
private var secondImage: UIImage? { didSet { reevaluateImagesSet() } }
private func reevaluateImagesSet() {
imageView1.image = firstImage
imageView2.image = secondImage
if let firstImage = firstImage, let secondImage = secondImage {
applyCombinedImage(firstImage, secondImage)
}
}
private func applyCombinedImage(_ firstImage: UIImage, _ secondImage: UIImage) {
// do the bitwise operation of yours in here
}
Now the only problem is how to define which image you are setting.现在唯一的问题是如何定义您正在设置的图像。 You could use a boolean flag or create a custom class which makes things like so:
您可以使用 boolean 标志或创建自定义 class ,这样可以:
@IBAction private func selectFirstImagePressed() {
let picker = MyPicker(controller: self)
self.currentPicker = picker
picker.selectImage { image in
self.firstImage = image
}
}
@IBAction private func selectSecondImagePressed() {
let picker = MyPicker(controller: self)
self.currentPicker = picker
picker.selectImage { image in
self.secondImage = image
}
}
This class MyPicker
then corresponds to PHPickerViewControllerDelegate
and implements the logic to only return an image in a provided closure.然后,此 class
MyPicker
对应于PHPickerViewControllerDelegate
并实现仅在提供的闭包中返回图像的逻辑。 I hope you will have no problems implementing it.我希望你在实施它时不会遇到任何问题。 It is mostly extracting the code that you already have.
它主要是提取您已经拥有的代码。
The problem is the line问题是线路
self.isBitwisePick = false
In your didFinishPicking() function.在您的 didFinishPicking() function 中。 That line will execute before the completion handler of your itemProvider.loadObject(ofClass:) function is called.
该行将在调用 itemProvider.loadObject(ofClass:) function 的完成处理程序之前执行。 Then when you check isBitwisePick in your completion handler, it will be false.
然后,当您在完成处理程序中检查 isBitwisePick 时,它将是错误的。 You should move that line inside your completion handler.
您应该在完成处理程序中移动该行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.