首页 > 解决方案 > 以编程方式创建的约束有问题

问题描述

我正在使用 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(),

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

}

标签: iosswiftconstraints

解决方案


问题就在这里

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

}

推荐阅读