微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何获得弹出自定义modalPresentationStyle VC

如何解决如何获得弹出自定义modalPresentationStyle VC

当出现 VC 时,认样式不是全屏覆盖,而是带有圆角,如下图所示。

gif

但是我想控制modalPresentation的高度,假设认为1/4屏幕高度,并且根据tableView弹出的VC行动态改变。所以我在代码下面的基础 VC 上实现了一个 custom modalPresentationStyle。

但是,我在之后发现了这些问题:

  1. 弹出的VC不是圆角而是矩形角。
  2. 我不能再拖动来移动弹出的 VC,它处于固定位置。
  3. 如果我可以根据 tableView 行数增加弹出的 VC 的高度会更好。不是必需品。
    @objc func collectButtonTapped(_ sender: Any?) {
        
        let vc = PlayListViewController()
        vc.modalPresentationStyle = .custom
        vc.transitioningDelegate = self
        
        present(vc,animated: true)
        
    }
    
    func presentationController(forPresented presented: UIViewController,presenting: UIViewController?,source: UIViewController) -> UIPresentationController? {
        return HalfSizePresentationController(presentedViewController: presented,presenting: presentingViewController)
    }

class HalfSizePresentationController: UIPresentationController {
    override var frameOfPresentedViewInContainerView: CGRect {
        guard let bounds = containerView?.bounds else { return .zero }
        return CGRect(x: 0,y: bounds.height * 0.75,width: bounds.width,height: bounds.height * 0.75)
    }
}

解决方法

尝试将cornerRadius分配给您的vc:

@objc func collectButtonTapped(_ sender: Any?) {
    
    let vc = PlayListViewController()
    vc.modalPresentationStyle = .custom
    vc.transitioningDelegate = self
    // assign corner radius
    vc.view.layer.cornerRadius = 20
    vc.view.clipsToBounds = true
    vc.view.layer.maskedCorners = [.layerMaxXMinYCorner,.layerMinXMinYCorner] // this is for corner radius only for top
    present(vc,animated: true)
}

对于vc呈现位置的完全控制,您可以使用子vc和自动布局,对于当前子vc(如模态呈现样式),您可以在子vc顶部约束上使用UIView.animate。

这是一个子vc和自动布局的例子:

import UIKit

class YourController: UIViewController {

private lazy var firstChildVc = AiutiFirst()

let myButton: UIButton = {
    let b = UIButton(type: .system)
    b.layer.cornerRadius = 10
    b.clipsToBounds = true
    b.backgroundColor = .black
    b.setTitleColor(.white,for: .normal)
    b.setTitle("Present",for: .normal)
    b.addTarget(self,action: #selector(handlePresent),for: .touchUpInside)
    b.translatesAutoresizingMaskIntoConstraints = false
    
    return b
}()

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .blue
    addChildVC()
}

var up = false

@objc fileprivate func handlePresent() {
    
    print("present")
    
    if up == false {
        UIView.animate(withDuration: 0.3,delay: 0,options: .curveEaseOut) {
            self.menuDown?.isActive = false
            self.menuUp?.isActive = true
            self.myButton.setTitle("Dismiss",for: .normal)
            self.view.layoutIfNeeded()
        } completion: { _ in
            print("Animation completed")
            self.up = true
        }
    } else {
        UIView.animate(withDuration: 0.3,options: .curveEaseOut) {
            self.menuUp?.isActive = false
            self.menuDown?.isActive = true
            self.myButton.setTitle("Present",for: .normal)
            self.view.layoutIfNeeded()
        } completion: { _ in
            print("Animation completed")
            self.up = false
        }
    }
}

var menuUp: NSLayoutConstraint?
var menuDown: NSLayoutConstraint?

fileprivate func addChildVC() {
    addChild(firstChildVc)

    firstChildVc.view.translatesAutoresizingMaskIntoConstraints = false

    firstChildVc.view.layer.cornerRadius = 20
    firstChildVc.view.clipsToBounds = true
    firstChildVc.view.layer.maskedCorners = [.layerMaxXMinYCorner,.layerMinXMinYCorner] // this is for corner radius only for top
    
    view.addSubview(firstChildVc.view)

    menuUp = firstChildVc.view.topAnchor.constraint(equalTo: view.centerYAnchor)
    menuDown = firstChildVc.view.topAnchor.constraint(equalTo: view.bottomAnchor)
    menuDown?.isActive = true
    firstChildVc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    firstChildVc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    firstChildVc.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    firstChildVc.didMove(toParent: self)
    
    view.addSubview(myButton)
    myButton.bottomAnchor.constraint(equalTo: view.centerYAnchor,constant: -40).isActive = true
    myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
    myButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
    myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
 }
}

这是结果:

enter image description here

要动画子 vc 演示文稿,您可以使用 UIView.animate 函数作为顶部子 vc 约束,或平移手势拖动它,或任何您认为必要且有效的使用...

显示全屏简单设置子vc顶部锚点到intere视图的顶部:

menuUp = firstChildVc.view.topAnchor.constraint(equalTo: view.topAnchor)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。