在iOS 13中,模态视图 Controller 出现了一个新行为,我发现内置的App Photo呈现了一个较小的模型 View Controller 。
我该如何呈现一个具有这样自定义尺寸的viewController,并且可以将其滑到更大的高度?
来自系统照片应用程序的图片截图。
最佳答案
迅速回答
我一直在寻找一种方法来复制这种类型的ViewController行为,尽管它具有基本的UI,并且找到了一个相当简单的解决方案。
基本上,您将创建一个具有透明背景的ViewController(CardViewContoller
),然后将其添加到带有UIPanGestureReconizer
的卡片式 View 中,这将使您可以将其拖动并通过ViewController将其关闭。
要演示您只需调用present
,将modalPresentationStyle
设置为.overCurrentContext
,将modalTransitionStyle
设置为.coverVertical
:
let cardVC = CardViewController()
cardVC.modalPresentationStyle = .overCurrentContext
cardVC.modalTransitionStyle = .coverVertical
present(cardVC, animated: true, completion: nil)
在
CardViewController
中,可以通过编程方式创建或使用Interface Builder将其添加到卡 View (UIPanGestureRecognizer
)中:let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleDismiss(recognizer:)))
panGestureRecognizer.cancelsTouchesInView = false
contentView.addGestureRecognizer(panGestureRecognizer)
然后只需添加一个
contentView
函数即可响应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
}
}
@objc
是一个swipeThreshold
变量,您可以选择一个值(200对我而言非常有用),如果CGFloat
y转换超出范围,将触发ViewController及其所有元素的关闭。同样,您可以添加一个简单的按钮,该按钮将关闭
UIPanGestureRecognizer
上的ViewController并调用.touchUpInside
如果需要,可以查看this repo,其中有一个展示此行为的示例项目。这样,您可以构建自己的完全可定制的卡。