IcaliaLabs / Presentr

Swift wrapper for custom ViewController presentations on iOS
MIT License
3.07k stars 270 forks source link

How to manage safe area constraints on presented view controller during interactive presentation? #169

Open bernikovich opened 5 years ago

bernikovich commented 5 years ago

Hello guys. I have faced with an issue related to safe area during interactive presentation. Does someone knows how to fix it?

I have added in PresentrExample.MainTableViewController -> lazy var alertViewController following codeL

        if #available(iOS 11.0, *) {
            let custom = UIView()
            custom.backgroundColor = UIColor.red.withAlphaComponent(0.5)
            custom.translatesAutoresizingMaskIntoConstraints = false
            alertController.view.addSubview(custom)
            NSLayoutConstraint.activate([
                custom.leadingAnchor.constraint(equalTo: alertController.view.leadingAnchor),
                custom.trailingAnchor.constraint(equalTo: alertController.view.trailingAnchor),
                custom.bottomAnchor.constraint(equalTo: alertController.view.safeAreaLayoutGuide.bottomAnchor),
                custom.heightAnchor.constraint(equalToConstant: 50)
                ])
        }
bernikovich commented 5 years ago

First screenshot shows normal behavior. Second one with issue during interactive dismissal. simulator screen shot - iphone x - 2019-02-22 at 13 49 58 simulator screen shot - iphone x - 2019-02-22 at 13 50 05

bernikovich commented 5 years ago

SafeArea guide changes without animation. So user can see blink when my red view changes its place.

Anonym0uz commented 5 years ago

Hi, try to replace calculateCenterPoint func in ModalCenterPosition file on:

func calculateCenterPoint(_ containerFrame: CGRect) -> CGPoint? {
        var bottom: CGFloat = 0
        var top: CGFloat = 0
        if #available(iOS 11.0, *), let keyWindow = UIApplication.shared.keyWindow {
            if keyWindow.safeAreaInsets.bottom > 0 && keyWindow.safeAreaInsets.top > 0 {
                top = keyWindow.safeAreaInsets.top
                bottom = keyWindow.safeAreaInsets.bottom
            }
        }

        switch self {
        case .center:
            return CGPoint(x: containerFrame.origin.x + (containerFrame.width / 2),
                           y: containerFrame.origin.y + (containerFrame.height / 2))
        case .topCenter:
            return CGPoint(x: containerFrame.origin.x + (containerFrame.width / 2),
                           y: containerFrame.origin.y + (containerFrame.height * (1 / 4) - 1) + top)
        case .bottomCenter:
            return CGPoint(x: containerFrame.origin.x + (containerFrame.width / 2),
                           y: containerFrame.origin.y + (containerFrame.height * (3 / 4)) - bottom)
        case .custom(let point):
            return point
        case .customOrigin(_):
            return nil
        }
    }