ios - 以编程方式创建的约束有问题

标签 ios swift constraints

我正在使用 swift 5 为 iPhone 和 iPad 构建应用程序,但我遇到了一些约束问题。

首先,我创建了我需要的所有 View 、堆栈 View 和标签。

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

然后我设置堆栈 View 方向并将其添加到 View

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 - 横向 - PieChartView 需要更小
  • iPhone - 纵向 - PieChartView 可以更小
  • iPad - Portrait - PieChartView 太大了

这在 iPad 上看起来不错 - 横向

(附上屏幕截图)

我需要对我的约束做些什么才能让 PieChartView 适合 self.communityButton 和我在 PieChartView 下面的网格之间?

我已经尝试将 UIStackView 的底部约束设置到网格 topAnchor 的顶部,但是网格是 Shinobigrid 并且没有 topAnchor.....我该怎么办?

enter image description here enter image description here enter image description here enter image description here

更新:

我试过以下方法

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()

}

关于ios - 以编程方式创建的约束有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55937541/

相关文章:

mysql - 使用外键约束更新值

ios - iTunes 连接 : Can't save app information after uploading new binary

ios - 如何在 swift 中使用 api 通用管理器类删除传递数组作为参数的 json 解析错误?

ios - 如何在 TableView Controller 中放置文本字段以读取内容

ios - 在 Swift Playground 实例中运行 CoreLocation

ios - 如何在 UITableViewCell 中获取屏幕宽度?

ios - 具有多列的 TableViewCell

ios - 自动布局不是那么自动

android - 苹果开发商导出合规

iphone - 在查看另一个 TableView 后尝试查看 TableView 时,应用程序崩溃