使用 Objective C 向下滑动手势检测 imagePickerController 是否关闭

detect if imagePickerController is closed with swipe down gesture with Objective C

我正在尝试检测何时通过滑动关闭 imagePickerController 通过向下滑动手势或通过取消关闭。

imagePicker是通过这个方法加载的(https://developer.apple.com/documentation/uikit/uiviewcontroller/1621380-presentviewcontroller)

[rootViewController presentViewController:picker animated:animated completion:NULL];

我们可以通过实现这个方法(https://developer.apple.com/documentation/uikit/uiimagepickercontrollerdelegate/1619133-imagepickercontrollerdidcancel)

简单地通过取消检测pickerController是否被关闭

但是,我还想通过向下滑动来检测它是否关闭(对于 iPhone X,...,我们可以向下滑动以关闭模态显示的视图)

和Swift,我可以用这段代码检测到它:

extension UIImagePickerController {
    open override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // detecting
    }
}

我想知道这是否是在 objective C 中执行此操作的等效方法(因为我正在处理的项目是在 objective C 中编写的)?或欢迎任何其他建议:D

首先,您应该覆盖Swift中的扩展中的viewDidDisappear:(也不应Objective-C中的类别)。在 extension/category 中覆盖某些内容的结果是未定义的行为——它可能有效,也可能无效。永远不要依赖它。

相反,将图像选择器 presentationController 的委托分配给某些 class,然后让 class 实现 presentationControllerDidDismiss: 方法。在所有动画完成后,当用户成功关闭图像选择器时调用此方法。 (请注意,如果以编程方式关闭图像选择器,则 不会 调用它。)

这是一个简短的示例,涵盖了在无需覆盖扩展程序或类别中的 viewDidDisappear: 的情况下关闭图像选择器的所有情况:

@interface ViewController() <UIAdaptivePresentationControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>

@end

@implementation ViewController

- (IBAction)showImagePicker {
    UIImagePickerController *imagePicker = [UIImagePickerController new];
    imagePicker.delegate = self;
    imagePicker.presentationController.delegate = self;
    [self presentViewController:imagePicker animated:YES completion:nil];
}

#pragma mark - UIAdaptivePresentationControllerDelegate

- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController {
    NSLog(@"The user began to swipe down to dismiss.");
}

- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController {
    NSLog(@"The dismissal animation finished after the user swiped down.");

    // This is probably where you want to put your code that you want to call.
}

#pragma mark - UIImagePickerControllerDelegate, UINavigationControllerDelegate

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    NSLog(@"The user tapped the image picker's Cancel button.");
    [self dismissViewControllerAnimated:YES completion:^{
        NSLog(@"The dismissal animation finished after the user tapped Cancel.");
    }];
}

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey, id> *)info {
    NSLog(@"The user selected an image from the image picker.");
    [self dismissViewControllerAnimated:YES completion:^{
        NSLog(@"The dismissal animation finished after the user selected an image.");
    }];
}

@end

这里有一个 Swift 版本:

class ViewController: UIViewController {
    @IBAction func showImagePicker() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.presentationController?.delegate = self
        present(imagePicker, animated: true)
    }
}

extension ViewController: UIAdaptivePresentationControllerDelegate {
    func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
        print("The user began to swipe down to dismiss.")
    }

    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
        print("The dismissal animation finished after the user swiped down.")

        // This is probably where you want to put your code that you want to call.
    }
}

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        print("The user tapped the image picker's Cancel button.")
        dismiss(animated: true) {
            print("The dismissal animation finished after the user tapped Cancel.")
        }
    }

    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        print("The user selected an image from the image picker.")
        dismiss(animated: true){
            print("The dismissal animation finished after the user selected an image.")
        }
    }
}