ios - 如何获得弹出的自定义modalPresentationStyle VC的圆角和动态高度
问题描述
展示 VC 时,默认样式不覆盖全屏,并带有圆角,如下 gif 所示。
但是我想控制modalPresentation的高度,假设默认为1/4屏幕高度,并根据tableView弹出VC的行动态更改。所以我custom
在下面的代码基础上实现了一个 modalPresentationStyle 。
但是,我在之后发现了这些问题:
- 弹出的 VC 不是圆角,而是矩形角。
- 我不能再拖动来移动弹出的 VC,它处于固定位置。
- 如果我可以根据其 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, delay: 0, 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
}
}
这是结果:
要为子 vc 演示动画制作动画,您可以将 UIView.animate 函数用于顶级子 vc 约束,或者使用平移手势拖动它,或者任何您认为必要且有效的使用...
显示它全屏简单设置子 vc 顶部锚点到兴趣视图顶部:
menuUp = firstChildVc.view.topAnchor.constraint(equalTo: view.topAnchor)
推荐阅读
- angular7 - 用逗号 angular7 / ionic4 显示价格小数点后 2 位
- python - 错误消息:TypeError:需要一个类似字节的对象,而不是在 Python 中使用 Pickle 接收到的“str”
- python - 使用 set_table_styles() 时,如何将格式应用于具有多级列索引的数据框?
- jquery - 在 HTML 模板中选择元素并附加到正文
- javascript - 如何使用 Firebase 函数检查 Firebase 实时数据库中是否存在值?
- c# - 从对象列表中获取 n 个(部分)对象,从 n 个索引开始
- python - Pandas - DateTime groupby 到结构化字典
- php - laravel voyager mb_strlen() 期望参数 1 是字符串,给定数组
- powerbi - LOOKUPVALUE 返回舍入值
- regex - 用于在名字/姓氏之间添加逗号和空格的正则表达式