[SWIFT] About Popover fix for iOS 13

Introduction

It seems that the overlapping order of popover masks has changed from iOS 13 now. .. .. When I noticed, the picker etc. displayed by popover was cut off, so I will summarize the correction method as a memorandum.

environment

swift5 Xcode 11.4.1

Before correction

The UI shift is like this. When there are arrows on the left and right, it will be clearly cut off.

By the way, the original implementation was like this.

hoge.swift



//Image Picker display
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.modalPresentationStyle = .popover
imagePicker.mediaTypes = [kUTTypeMovie as String]
        
let popover = imagePicker.popoverPresentationController
popover?.sourceView = button
popover?.sourceRect = button.bounds
        
present(imagePicker, animated: true, completion: nil)

How to fix

I have created an extension for UIViewController.

UIViewController+Picker.swift


extension UIViewController {

    ///Create a VC for Picker and display Picker(For imagePicker)
    ///
    /// - Parameters:
    ///   - imagePickerController: UIImagePickerController
    ///   - source:View that is the display source of picker
    func presentPickerView(_ imagePickerController: UIImagePickerController, source: UIView) {
        guard let imagePickerView = imagePickerController.view else { return }
        //Create a base VC
        let customPickerViewController = UIViewController()
        //AddChild first
        customPickerViewController.addChild(imagePickerController)
        //Make the base VC and imagePicker the same size
        imagePickerController.view.frame = customPickerViewController.view.frame
        //Set to false when specifying AutoLayout in the code for a view that can be a subView
        imagePickerController.view.translatesAutoresizingMaskIntoConstraints = false
        //addSubview
        customPickerViewController.view.addSubview(imagePickerView)
        //Here, we will specify the restrictions of ImagePicker for the safaArea of the base VC.
        NSLayoutConstraint.activate([
            imagePickerController.view.leadingAnchor.constraint(equalTo:
                customPickerViewController.view.safeAreaLayoutGuide.leadingAnchor),
            imagePickerController.view.trailingAnchor.constraint(equalTo:
                customPickerViewController.view.safeAreaLayoutGuide.trailingAnchor),
            imagePickerController.view.topAnchor.constraint(equalTo:
                customPickerViewController.view.safeAreaLayoutGuide.topAnchor),
            imagePickerController.view.bottomAnchor.constraint(equalTo:
                customPickerViewController.view.safeAreaLayoutGuide.bottomAnchor)
        ])
        //set completed with didMove
        imagePickerController.didMove(toParent: customPickerViewController)

        //The following returns to the basic implementation of picker.
        //Specify the size for the base View(=The size of the picker)
        customPickerViewController.preferredContentSize = CGSize(width: 200,
                                                                 height: 200)
        customPickerViewController.modalPresentationStyle = .popover
        let popover = customPickerViewController.popoverPresentationController
        popover?.sourceView = source
        popover?.sourceRect = source.bounds

        present(customPickerViewController, animated: true, completion: nil)
    }
}

When using it, it looks like this

ViewController.swift



@IBOutlet func TapButton(_ sender: UIButton) {
    //Create the picker you want to display
    let imagePicker = UIImagePickerController()
    //Set delegate etc. in the displayed class
    imagePicker.delegate = self
    imagePicker.sourceType = .photoLibrary
    //Display using extension
    presentPickerView(imagePicker, source: button)
}

end.

Recommended Posts

About Popover fix for iOS 13
Introduction to kotlin for iOS developers ③-About gradle
About for statement and if statement
Find out about annotationProcessor for Gradle 5.0
[For our newcomers] About isXXX methods
[For Java beginners] About exception handling