在iOS 13中以自定义高度呈现模态视图

13
在iOS 13中,模态视图控制器的呈现方式有了新的行为。我发现内置应用程序照片呈现了一个较小的模态视图控制器。
我如何呈现一个自定义大小的视图控制器,就像这样,并且可以向上滑动到更大的高度?

smaller height

larger height

从系统照片应用中获取图片截图。


4
@AshishKakkad,这不是同一个问题。我的问题集中在viewController的高度上。 - jrjian
2个回答

11

是的,使用自定义高度在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
    }
 }

9

用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 = 200var viewTranslation = CGPoint(x: 0, y: 0) - Drew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接