在iOS 13中,模态视图控制器的呈现方式有了新的行为。我发现内置应用程序照片呈现了一个较小的模态视图控制器。
我如何呈现一个自定义大小的视图控制器,就像这样,并且可以向上滑动到更大的高度?
我如何呈现一个自定义大小的视图控制器,就像这样,并且可以向上滑动到更大的高度?
从系统照片应用中获取图片截图。
从系统照片应用中获取图片截图。
是的,使用自定义高度在iOS 13中展示模态框是可能的。 你只需将以下代码添加到你的模态框中。
override func updateViewConstraints() {
self.view.frame.size.height = UIScreen.main.bounds.height - 150
self.view.frame.origin.y = 150
self.view.roundCorners(corners: [.topLeft, .topRight], radius: 10.0)
super.updateViewConstraints()
}
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
用Swift回答
我想找一种方法来模仿那种视图控制器的行为,尽管只有基本的UI,并且找到了一个相当简单的解决方案。
基本上,您创建一个带有透明背景的视图控制器(CardViewContoller
),然后向其中添加一个类似于卡片的视图,具有UIPanGestureReconizer
,这将使您能够拖动它并将其与视图控制器一起关闭。
要呈现您所需的只需调用present
,将modalPresentationStyle
设置为.overCurrentContext
,将modalTransitionStyle
设置为.coverVertical
:
let cardVC = CardViewController()
cardVC.modalPresentationStyle = .overCurrentContext
cardVC.modalTransitionStyle = .coverVertical
present(cardVC, animated: true, completion: nil)
CardViewController
中,可以通过编程或使用Interface Builder创建,向卡片视图(contentView
)添加一个UIPanGestureRecognizer
:let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleDismiss(recognizer:)))
panGestureRecognizer.cancelsTouchesInView = false
contentView.addGestureRecognizer(panGestureRecognizer)
接着只需添加一个@objc
函数以响应UIPanGestureRecognizer:
@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 关闭以及所有元素的关闭。
同样,您可以添加一个简单的按钮,在 .touchUpInside
时调用 dismiss()
来关闭 ViewController。CardViewController
还需要 let swipeThreshold: CGFloat = 200
和 var viewTranslation = CGPoint(x: 0, y: 0)
。 - Drew