在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,其中有一个展示此行为的示例项目。这样,您可以构建自己的完全可定制的卡。

10-07 19:39
查看更多