IOS 13では、モーダルビューコントローラーが表示されるときの新しい動作があり、組み込みのApp Photoが小さいモデルのビューコントローラーを表示することがわかりました。
このようにカスタムサイズのviewControllerを表示して、より高い高さまでスライドさせるにはどうすればよいですか。
システム写真アプリからの画像のスクリーンショット。
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を使用して作成できるCardViewController
のUIPanGestureRecognizer
をカードビューに追加します(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
}
}
_
swipeThreshold
はCGFloat
変数であり、選択した値(200は私に最適です)、UIPanGestureRecognizer
y変換が超過した場合、すべての要素とともにViewControllerの終了をトリガーします。同様に、dismiss()
を呼び出す_.touchUpInside
_でViewControllerを閉じる単純なボタンを追加できます。
必要に応じて、この動作を示すサンプルプロジェクトがある this repo をご覧ください。そうすれば、完全にカスタマイズ可能な独自のカードを作成できます。
これは、標準のUIViewController実装では実現できないと思います。つまり、iOS 13の新しいプレゼンテーションスタイルでも、プレゼンテーションの高さを設定するだけです。
次のようなサードパーティのソリューションを検討する(または、ソリューションからインスピレーションを得る)ことができます。