UIViewController 的动态高度显示为模式弹出窗口
Posted
技术标签:
【中文标题】UIViewController 的动态高度显示为模式弹出窗口【英文标题】:Dynamic height for UIViewController shown as modal popup 【发布时间】:2019-01-05 19:23:00 【问题描述】:我目前正在尝试实现一个自定义UIViewController
,其中包含一个UINavigationController
。这是一个模态视图,将在屏幕底部可见,用户可以在此模态视图内导航有不同的选项。 UIViewController
的背景设置为清除,因此它显示为已经可见屏幕的覆盖。
我现在已经设法像这样设置和展示我的UIViewController
:
let modalController = ModalController()
modalController.modalPresentationStyle = .overCurrentContext
self.present(modalController, animated: true, completion: nil)
在这个UIViewController
里面我是这样做的:
var popupController: UINavigationController =
let popupController = UINavigationController(rootViewController: ModalStart())
return popupController
()
var modalPopup: UIView =
let modalPopup = UIView()
modalPopup.translatesAutoresizingMaskIntoConstraints = false
modalPopup.backgroundColor = .white
modalPopup.isUserInteractionEnabled = true
return modalPopup
()
view.addSubview(modalPopup)
modalPopup.addSubview(popupController.view)
modalPopup.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
modalPopup.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
modalPopup.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
modalPopup.heightAnchor.constraint(equalToConstant: 500).isActive = true
这很好用,但您可能已经猜到了,高度设置为 500 的固定常数。这适用于我的 iPhone X,但在 iPhone 5s 上会有所不同。当我浏览UINavigationController
时,它也不允许我相应地更改高度,因为不同viewControllers
的高度会有所不同。
有谁知道我如何做到这一点?我已经在我的rootViewController
(ModalStart) 中添加了一个自定义 ContainerView,但我无法直接访问 popupController.containerView.frame.height(因为 popupController 是一个UINavigationController
)。我还尝试将 heightAnchor 设为变量并将其设置在 ModalStart() 的 viewDidLayoutSubviews()
中,但这也不起作用,并且会以不同的高度不断触发(如果我打印高度,它有时会返回 480,有时会返回 0,非常那里有奇怪的行为)。
我想知道对于我的具体情况最好的方法是什么。非常感谢任何指出我正确方向的东西!
【问题讨论】:
modalpopup.topanchor 工作了吗? 你是什么意思?我可以设置modalPopup.topAnchor,是的。如果我将它限制在视图的 topAnchor 上,并设置一个常数,比如说 300,它显示得非常好。但这不是动态的。我试图在 viewDidLayoutSubviews() 之后计算 containerView 的高度,并用整个屏幕的高度减去然后计算的 containerView 的高度来相应地更改它。这最初是可行的,但后来我无法更改高度,因为 popupController 的高度(内部有 UINavigationController)保持与初始高度相同。 为什么不将 heightAnchor 设置为取决于 screenSize 的常量。例如modalPopup.heightAnchor.constraint(equalToConstant: UIScreen.main.bounds.height/yourConstant).isActive = true
这样你就可以让它根据屏幕大小动态工作。如果您不想使用 UIScreen 大小,也可以使用 ViewController 边界
那不允许我根据子视图设置高度。有一些子视图可以有不同的高度,例如多行 UILabel。当 UINavigationController 被推送到另一个具有另一个高度的视图时,也很难相应地更改高度。
你能张贴你想要得到的截图吗?我有点难以理解。
【参考方案1】:
我将向您展示一个简单的方法。据我所见,最好的方法是使用 modalView 的 dataSource 模型并从那里计算高度。例如,如果您有一个图像和一个标签,哪些高度是已知的,如果不能计算,您可以将其作为 modalView 的数据源发送。现在,如果下一个 modalView 将只有 6 个标签,那么再次计算出适合所有标签所需的高度将很容易。通过使用 dataSource 模型,您可以在过渡到下一个 modalView 之前预先计算所有高度。我在这里为您整理了一个简单的示例:https://github.com/galots/VariableModal
如果您单击显示为 Present 的按钮,则会显示新的 viewController,并且 modalView 将显示初始约束。然后,如果您单击下一步,模态视图高度将根据数据源进行相应更新。在这种情况下,dataSource 只是一个CGFloat
的数组,只是为了便于理解。此外,请注意 modalView 是 UIView
的子类,因此您可以根据需要更新其高度约束。
希望对你有帮助。
【讨论】:
感谢您的努力!然而,我似乎无法找到相关代码,当我在 Xcode 中运行时,我什么也看不到,只有一个白色窗口。能否链接到相关代码或文件? 对不起。发布时出错。给你:github.com/galots/VariableModal 哇,太棒了!非常感谢您的榜样!以上是关于UIViewController 的动态高度显示为模式弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章