iOS 11双击图像将解除UIImagePickerController和presenter视图控制器
我们有一个用iOS 11双击图像将解除UIImagePickerController和presenter视图控制器,ios,swift,ios11,Ios,Swift,Ios11,我们有一个用UIImagePickerController制作的照片采集器 制作双击时,点击(而不是one点击)多媒体资料中的照片 在iOS 10上:UIImagePickerController被解除 在iOS 11上:UIImagePickerController被解除,并且显示视图控制器也被解除:0 是iOS 11错误还是我们必须调整 我们的守则: let vc = UIImagePickerController() vc.delegate = self vc.modal
UIImagePickerController
制作的照片采集器
制作双击时,点击(而不是one点击)多媒体资料中的照片
- 在iOS 10上:
被解除UIImagePickerController
- 在iOS 11上:
被解除,并且显示视图控制器也被解除:0UIImagePickerController
我们的守则:
let vc = UIImagePickerController()
vc.delegate = self
vc.modalPresentationStyle = .overFullScreen
vc.allowsEditing = false
rootVC.present(vc, animated: true) // `rootVC` also presented modally.
我们最终的解决方案是:在代理调用
did完成pickingMediaWithInfo
后立即设置delegate=nil
public class ImagePicker: NSObject {
private lazy var viewController = setupActionSheet()
private var rootViewController: UIViewController?
private var completionHandler: (([String: Any]) -> Void)?
private var cancellationHandler: (() -> Void)?
}
extension ImagePicker {
public func present(on: UIViewController, completionHandler: @escaping (([String: Any]) -> Void)) {
rootViewController = on
self.completionHandler = completionHandler
cancellationHandler = nil
on.presentAnimated(viewController)
}
public func present(on: UIViewController,
completionHandler: @escaping (([String: Any]) -> Void),
cancellationHandler: @escaping (() -> Void)) {
rootViewController = on
self.completionHandler = completionHandler
self.cancellationHandler = cancellationHandler
on.presentAnimated(viewController)
}
}
extension ImagePicker {
private func setupActionSheet() -> UIAlertController {
let actionSheet = UIAlertController(actionSheetWithTitle: LocalizedString.Generic.ImagePicker.addPhoto)
if UIImagePickerController.isSourceTypeAvailable(.camera) {
actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.takePhoto) { [weak self] _ in
self?.presentImagePicker(.camera)
}
}
actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.selectPhoto) { [weak self] _ in
self?.presentImagePicker(.photoLibrary)
}
actionSheet.addCancelAction(LocalizedString.Generic.ButtonTitle.cancel) { [weak self] _ in
self?.cancellationHandler?()
}
return actionSheet
}
private func presentImagePicker(_ sourceType: UIImagePickerControllerSourceType) {
let vc = UIImagePickerController()
vc.delegate = self
vc.allowsEditing = false
vc.sourceType = sourceType
rootViewController?.present(vc, animated: true)
}
}
extension ImagePicker: UIImagePickerControllerDelegate {
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
picker.delegate = nil /// It prevents to call delegate when user taps on a few images very fast. seems iOS 11 issue only.
if picker.sourceType == .camera, let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
picker.dismiss(animated: true) {
self.completionHandler?(info)
}
}
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true) {
self.cancellationHandler?()
}
}
}
用法:
// Somewhere in view controller code.
imagePicker = ImagePicker()
imagePicker?.present(on: self) { [weak self] in
self?.imagePicker = nil
self?.viewModel.addImage($0)
}
使用picker.disclease()代替self.disclease()
这只会关闭选择器视图,而不会关闭视图控制器。我也面临同样的问题,可能是错误。解决了吗?如果使用Dismise方法的完成处理程序执行进一步的活动,请更新答案,例如[self DismissViewControllerInitiated:YES completion:^{[self-saveImage:image];}];我们通过在委托调用之后立即设置
delegate=nil
进行修复。请参阅下面的新答案。将委托设置为零在设备上似乎不起作用。问题是didFinishPickingMediaWithInfo会被多次调用,因此如果我们在didFinishPickingMediaWithInfo中使用Disclose,它会被多次调用,从而导致出现问题您是否在completionHandler
的回调中为您调用Disclose<代码>解除仅在选择器上调用
。示例代码已更新。这实际上对我不起作用,因为当双击照片时,委托方法似乎不会被调用两次。相反,图像采集器似乎在自我否定。具体地说,如果我注释掉picker.discome…它仍然会在调用didSelectImage委托方法后关闭picker。注意:在我的场景中,委托被解除分配,作为初始调用选择器回调的副作用。在双击过程中,图像选择器控制器可能会决定自行关闭。事实似乎确实如此,因为阻止释放委托会阻止选择器关闭显示视图控制器。
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
//self.dismiss(animated: true, completion: nil)
picker.dismiss(animated: true, completion: nil)
}