web-dev-qa-db-ja.com

カスタムの高さでモーダルをiOS 13で表示する

IOS 13では、モーダルビューコントローラーが表示されるときの新しい動作があり、組み込みのApp Photoが小さいモデルのビューコントローラーを表示することがわかりました。

このようにカスタムサイズのviewControllerを表示して、より高い高さまでスライドさせるにはどうすればよいですか。

smaller height

larger height

システム写真アプリからの画像のスクリーンショット。

6
jrjian

Swiftで回答

基本的なUIでありながら、このタイプのViewControllerの動作を再現する方法を探していて、かなり単純な解決策を見つけました。基本的には、背景が透明なViewController(CardViewContoller)を作成し、それにUIPanGestureReconizerを使用したカードのようなビューを追加します。これにより、ドラッグして周囲を閉じることができます。 ViewController。

提示するには、単にpresentを呼び出し、modalPresentationStyleを_.overCurrentContext_に設定し、modalTransitionStyleを_.coverVertical_に設定します。

_let cardVC = CardViewController()
cardVC.modalPresentationStyle = .overCurrentContext
cardVC.modalTransitionStyle = .coverVertical
present(cardVC, animated: true, completion: nil)
_

プログラムまたはInterface Builderを使用して作成できるCardViewControllerUIPanGestureRecognizerをカードビューに追加します(contentView):

_let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleDismiss(recognizer:)))
panGestureRecognizer.cancelsTouchesInView = false
contentView.addGestureRecognizer(panGestureRecognizer)

_

次に、UIPanGestureRecognizerに応答する_@objc_関数を追加します。

_    @objc
    func handleDismiss (recognizer: UIPanGestureRecognizer) {
        switch recognizer.state {
        case .changed:
            viewTranslation = recognizer.translation(in: view)
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                guard self.viewTranslation.y > 0 else {return}
                self.view.transform = CGAffineTransform(translationX: 0, y: self.viewTranslation.y)
            })
        case .ended:
            if viewTranslation.y < swipeThreshold {
                UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                    self.view.transform = .identity
                })
            } else {
                dismiss(animated: true, completion: nil)
            }
        default:
            break
        }
    }
_

swipeThresholdCGFloat変数であり、選択した値(200は私に最適です)、UIPanGestureRecognizer y変換が超過した場合、すべての要素とともにViewControllerの終了をトリガーします。同様に、dismiss()を呼び出す_.touchUpInside_でViewControllerを閉じる単純なボタンを追加できます。

必要に応じて、この動作を示すサンプルプロジェクトがある this repo をご覧ください。そうすれば、完全にカスタマイズ可能な独自のカードを作成できます。

2

これは、標準のUIViewController実装では実現できないと思います。つまり、iOS 13の新しいプレゼンテーションスタイルでも、プレゼンテーションの高さを設定するだけです。

次のようなサードパーティのソリューションを検討する(または、ソリューションからインスピレーションを得る)ことができます。

https://github.com/MarioIannotta/PullUpController

0
Ash Cameron