ios - 以编程方式创建的约束有问题
问题描述
我正在使用 swift 5 为 iPhone 和 iPad 构建一个应用程序,但我遇到了一些约束问题。
首先,我创建了我需要的所有视图、堆栈视图和标签。
let st = UIStackView()
let st1 = UIStackView()
let st2 = UIStackView()
let underConstructionStackView = UIStackView()
let scheduleJobsStackView = UIStackView()
let withoutScheduleStackView = UIStackView()
let withoutPMStackView = UIStackView()
var underConstruction = PieChartView()
var scheduleJobs = PieChartView()
var withoutSchedule = PieChartView()
var withoutPM = PieChartView()
var underConstructionLabel = UILabel()
var scheduleJobsLabel = UILabel()
var withoutScheduleLabel = UILabel()
var withoutPMLabel = UILabel()
然后我将所有这些项目的 translatesAutoresizingMaskIntoConstraints 设置为 false:
st.translatesAutoresizingMaskIntoConstraints = false
underConstruction.translatesAutoresizingMaskIntoConstraints = false
scheduleJobs.translatesAutoresizingMaskIntoConstraints = false
withoutSchedule.translatesAutoresizingMaskIntoConstraints = false
withoutPM.translatesAutoresizingMaskIntoConstraints = false
underConstructionLabel.translatesAutoresizingMaskIntoConstraints = false
scheduleJobsLabel.translatesAutoresizingMaskIntoConstraints = false
withoutScheduleLabel.translatesAutoresizingMaskIntoConstraints = false
withoutPMLabel.translatesAutoresizingMaskIntoConstraints = false
然后我设置堆栈视图方向并将其添加到视图中
let size = UIScreen.main.bounds.size
if size.width < size.height {
st.axis = .horizontal
st1.axis = .vertical
st2.axis = .vertical
} else {
st.axis = .horizontal
st1.axis = .horizontal
st2.axis = .horizontal
}
underConstructionStackView.axis = .vertical
scheduleJobsStackView.axis = .vertical
withoutScheduleStackView.axis = .vertical
withoutPMStackView.axis = .vertical
st.distribution = .fill
st.alignment = .center
view.addSubview(st)
st.addArrangedSubview(st1)
st.addArrangedSubview(st2)
underConstructionStackView.addArrangedSubview(underConstructionLabel)
underConstructionStackView.addArrangedSubview(underConstruction)
st1.addArrangedSubview(underConstructionStackView)
scheduleJobsStackView.addArrangedSubview(scheduleJobsLabel)
scheduleJobsStackView.addArrangedSubview(scheduleJobs)
st1.addArrangedSubview(scheduleJobsStackView)
withoutScheduleStackView.addArrangedSubview(withoutScheduleLabel)
withoutScheduleStackView.addArrangedSubview(withoutSchedule)
st2.addArrangedSubview(withoutScheduleStackView)
withoutPMStackView.addArrangedSubview(withoutPMLabel)
withoutPMStackView.addArrangedSubview(withoutPM)
st2.addArrangedSubview(withoutPMStackView)
st1.distribution = .fillEqually
st2.distribution = .fillEqually
然后我以编程方式创建了约束:
NSLayoutConstraint.activate([
st.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
st.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
st.topAnchor.constraint(equalTo: self.communityButton.topAnchor,constant:60),
underConstruction.widthAnchor.constraint(equalTo: underConstruction.heightAnchor),
scheduleJobs.widthAnchor.constraint(equalTo: scheduleJobs.heightAnchor),
withoutSchedule.widthAnchor.constraint(equalTo: withoutSchedule.heightAnchor),
withoutPM.widthAnchor.constraint(equalTo: withoutPM.heightAnchor),
])
我的问题是 PieChartView(),
- iPhone - Landscape - PieChartView 需要更小
- iPhone - Portrait - PieChartView 可能会更小
- iPad - Portrait - PieChartView 太大了
这在 iPad 上看起来不错 - 横向
(附截图)
我需要对我的约束做些什么才能让 PieChartView 适合 self.communityButton 和我在 PieChartView 下方的网格?
我尝试将 UIStackView 的底部约束设置为网格 topAnchor 的顶部,但是网格是 Shinobigrid 并且没有 topAnchor ......我该怎么办?
更新:
我试过以下
if size.width < size.height
{
if UIDevice.current.userInterfaceIdiom == .pad {
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 1)
}
else
{
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.95)
}
}
else
{
if UIDevice.current.userInterfaceIdiom == .pad {
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.75)
}
else
{
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.75)
}
}
widthCon.isActive = true
在初始加载时,一切看起来都很棒......但是当我旋转设备时,一切都搞砸了。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.userInterfaceIdiom == .pad {
if UIDevice.current.orientation.isPortrait {
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.75)
}
else {
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 1)
}
}
else {
if UIDevice.current.orientation.isPortrait {
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.50)
}
else{
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.75)
}
}
self.view.layoutIfNeeded()
}
解决方案
问题就在这里
st.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
st.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
因为它填满了所有设备的屏幕,你需要用
var widthCon:NSLayoutConstraint!
//put inside activate
st.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)
// outside activate
widthCon = st.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.8)
widthCon.isActive = true
然后根据你需要勾选的组合做
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.userInterfaceIdiom == .pad {
if UIDevice.current.orientation.isPortrait {
//
widthCon.constant = size.width * 0.5 // lower it
}
else {
//
}
}
else {
if UIDevice.current.orientation.isPortrait {
//
}
else{
//
}
}
self.view.layoutIfNeeded()
}
推荐阅读
- sqlite - 计算给定月份满足条件的所有行
- html - 在 html 页面中运行表单时,我不断收到错误,指向 eclipse 中的另一个 html 页面
- node.js - 在运行 npm install 时接受用户输入后,我需要在我的 package.json 和加载模块中添加依赖项
- wordpress - 在 wordpress 中上传文件时出错“无法创建目录 wp-content/uploads。服务器可写其父目录吗?”
- python - 我需要使用 BeautifulSoup 从 2 个不同的跨度标签中获取文本
- javascript - selectionStart 不更新输入字段的焦点
- algorithm - 质数散列空间中的碰撞概率?
- python - 使用 Flask 流式传输多个视频?
- python-3.x - Python beeceptor webhook
- raspberry-pi - 您如何使您的项目可用,以便您可以在树莓派上将 OnOff 特征与谷歌助手一起使用?