swift如何以编程方式设置autolayout

qzlgjiam  于 2023-05-05  发布在  Swift
关注(0)|答案(2)|浏览(165)

我有一个视图内的按钮,在肖像模式,我想这样-

这是通过以下代码实现的-

//original potrait mode/////

 import UIKit
 class PotraitViewController: UIViewController {
 override func viewDidLoad() {
 let buttonred = UIButton()
 buttonred.backgroundColor = UIColor.red
 let buttonblue = UIButton()
 buttonblue.backgroundColor = UIColor.blue
 let landscapesmallview = UIView()
 view.addSubview(landscapesmallview)
 landscapesmallview.addSubview(buttonred)
 landscapesmallview.addSubview(buttonblue)
 buttonred.translatesAutoresizingMaskIntoConstraints = false
 buttonblue.translatesAutoresizingMaskIntoConstraints = false
 NSLayoutConstraint.activate([

    buttonred.topAnchor.constraint(equalTo: view.topAnchor,constant: 200),
    buttonred.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    buttonred.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant:-20),
    buttonred.widthAnchor.constraint(equalToConstant: 50),
    //-------
    buttonblue.topAnchor.constraint(equalTo: buttonred.bottomAnchor,constant: 40),
    buttonblue.leadingAnchor.constraint(equalTo: buttonred.leadingAnchor),
    buttonblue.trailingAnchor.constraint(equalTo:buttonred.trailingAnchor),
    buttonblue.widthAnchor.constraint(equalTo: buttonred.widthAnchor)

      ])
    }
  }

在横向模式下我想这样

这是通过以下代码实现的-

// original lanscape mode/////

import UIKit
class LandscapeViewController: UIViewController {
override func viewDidLoad() {
let buttonred = UIButton()
buttonred.backgroundColor = UIColor.red
let buttonblue = UIButton()
buttonblue.backgroundColor = UIColor.blue
view.addSubview(buttonred)
view.addSubview(buttonblue)
buttonred.translatesAutoresizingMaskIntoConstraints = false
buttonblue.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([

    buttonred.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    buttonred.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant:40),
    buttonred.trailingAnchor.constraint(equalTo: view.centerXAnchor,constant:-20),
    buttonred.widthAnchor.constraint(equalToConstant: 50),

    //-------
    buttonblue.centerYAnchor.constraint(equalTo: buttonred.centerYAnchor),
    buttonblue.leadingAnchor.constraint(equalTo: view.centerXAnchor,constant:40),
    buttonblue.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant:-20),
    buttonblue.widthAnchor.constraint(equalTo:buttonred.widthAnchor)

       ])
     }
  }

所以,我尝试了下面的代码来实现通过屏幕旋转即.两种不同的布局在potrait和风景视图编程与以下代码的帮助:-

import UIKit

class NewViewController: UIViewController {
override func viewDidLoad() {
let buttonredlandscape = UIButton()
buttonredlandscape.backgroundColor = UIColor.red
let buttonbluelandscape = UIButton()
buttonbluelandscape.backgroundColor = UIColor.blue
let buttonredportrait = UIButton()
buttonredportrait.backgroundColor = UIColor.red
let buttonblueportrait = UIButton()
buttonblueportrait.backgroundColor = UIColor.blue

let landscapesmallview = UIView()
let portraitsmallview = UIView()
landscapesmallview.backgroundColor = UIColor.gray
portraitsmallview.backgroundColor = UIColor.purple
landscapesmallview.frame = view.frame
portraitsmallview.frame = view.frame
view.addSubview(landscapesmallview)
view.addSubview(portraitsmallview)

landscapesmallview.addSubview(buttonredlandscape)
landscapesmallview.addSubview(buttonbluelandscape)
portraitsmallview.addSubview(buttonredportrait)
portraitsmallview.addSubview(buttonblueportrait)
buttonredlandscape.translatesAutoresizingMaskIntoConstraints = false
buttonbluelandscape.translatesAutoresizingMaskIntoConstraints = false
buttonredportrait.translatesAutoresizingMaskIntoConstraints = false
buttonblueportrait.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([

     buttonredlandscape.centerYAnchor.constraint(equalTo:landscapesmallview.centerYAnchor),
      buttonredlandscape.topAnchor.constraint(equalTo:landscapesmallview.topAnchor,constant:40),
    buttonredlandscape.trailingAnchor.constraint(equalTo:   landscapesmallview.centerXAnchor,constant:-20),
    buttonredlandscape.heightAnchor.constraint(equalTo:   landscapesmallview.heightAnchor,constant:50),

    buttonbluelandscape.centerYAnchor.constraint(equalTo:buttonredlandscape.centerYAnchor),
    buttonbluelandscape.leadingAnchor.constraint(equalTo: landscapesmallview.centerXAnchor,constant:40),
    buttonbluelandscape.trailingAnchor.constraint(equalTo: landscapesmallview.trailingAnchor,constant:-20),
    buttonbluelandscape.heightAnchor.constraint(equalTo: buttonredlandscape.heightAnchor),

    buttonredportrait.topAnchor.constraint(equalTo: portraitsmallview.topAnchor,constant: 200),
    buttonredportrait.centerXAnchor.constraint(equalTo: portraitsmallview.centerXAnchor),
    buttonredportrait.trailingAnchor.constraint(equalTo: portraitsmallview.trailingAnchor,constant:-20),
    buttonredportrait.widthAnchor.constraint(equalTo: buttonredportrait.widthAnchor),

    buttonblueportrait.topAnchor.constraint(equalTo: buttonredportrait.bottomAnchor,constant: 40),
    buttonblueportrait.leadingAnchor.constraint(equalTo: buttonredportrait.leadingAnchor),
    buttonblueportrait.trailingAnchor.constraint(equalTo:buttonredportrait.trailingAnchor),
    buttonblueportrait.widthAnchor.constraint(equalTo: buttonredportrait.widthAnchor)

     ])

//-------


func viewWillTransition(to size: CGSize, with coordinator:    ) {
    if UIDevice.current.orientation.isLandscape {
        landscapesmallview.translatesAutoresizingMaskIntoConstraints = false
        portraitsmallview.translatesAutoresizingMaskIntoConstraints = true
     } else if UIDevice.current.orientation.isPortrait {
        portraitsmallview.translatesAutoresizingMaskIntoConstraints = false
        landscapesmallview.translatesAutoresizingMaskIntoConstraints = true

        }
      }
    }
 }

其在肖像模式中示出-

在横向模式下显示-

如何通过编程实现我想要的,即。最上面的2个按钮,用于在用户每次旋转设备时以编程方式重新排列其自身。不仅仅是按钮。它可以是标签、图像、收藏视图等。或者随便什么其结果是,我想实现两个不同的布局,在风景和肖像模式编程无关的设备。
注意事项:
i)我已经尝试使用NSLayoutAnchor与“NSLayoutConstraint.activate”,因为苹果推荐它,但如果代码可以做得更短(更快)与一些其他的方法,如视觉格式等.我也没意见/
ii)如果可能的话,我不想使用stackview或containerview,因为可以有更多类型的标签,按钮等,但如果没有其他方法,那么我会使用它。
iii)我的代码是否符合DRY原则?

jmp7cifd

jmp7cifd1#

有多种方法可以做到这一点。一种方法:

  • 声明两个“约束”数组
  • 一个是持有“狭隘观点”的限制
  • 一个是保持“宽视野”的约束
  • 根据需要激活/取消激活约束

下面是一个完整的例子:

class ChangeLayoutViewController: UIViewController {

    let redButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        v.setTitle("Red Button", for: [])
        return v
    }()

    let blueButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .blue
        v.setTitle("Blue Button", for: [])
        return v
    }()

    var narrowConstraints: [NSLayoutConstraint] = [NSLayoutConstraint]()
    var wideConstraints: [NSLayoutConstraint] = [NSLayoutConstraint]()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(redButton)
        view.addSubview(blueButton)

        let g = view.safeAreaLayoutGuide

        var c: NSLayoutConstraint

        // MARK: - narrow orientation

        // constrain redButton above blueButton

        // constrain redButton leading and trailing to safe-area (with 8-pts on each side)
        c = redButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
        narrowConstraints.append(c)
        c = redButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
        narrowConstraints.append(c)

        // constrain blueButton leading and trailing to safe-area (with 8-pts on each side)
        c = blueButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
        narrowConstraints.append(c)
        c = blueButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
        narrowConstraints.append(c)

        // constrain redButton top 40-pts from safe-area top
        c = redButton.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0)
        narrowConstraints.append(c)
        // constrain blueButton top 20-pts from redButton bottom
        c = blueButton.topAnchor.constraint(equalTo: redButton.bottomAnchor, constant: 20.0)
        narrowConstraints.append(c)

        // MARK: - wide orientation

        // constrain redButton & blueButton side-by-side
        //  with equal widths and 8-pts between them

        // constrain redButton leading 8-pts from safe-area leading
        c = redButton.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0)
        wideConstraints.append(c)
        // constrain blueButton trailing 8-pts from safe-area trailing
        c = blueButton.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0)
        wideConstraints.append(c)

        // constrain blueButton leading 8-pts from redButton trailing
        c = blueButton.leadingAnchor.constraint(equalTo: redButton.trailingAnchor, constant: 8.0)
        wideConstraints.append(c)

        // constrain buttons to equal widths
        c = blueButton.widthAnchor.constraint(equalTo: redButton.widthAnchor)
        wideConstraints.append(c)

        // constrain both buttons centerY to safe-area centerY
        c = redButton.centerYAnchor.constraint(equalTo: g.centerYAnchor)
        wideConstraints.append(c)
        c = blueButton.centerYAnchor.constraint(equalTo: g.centerYAnchor)
        wideConstraints.append(c)

        // activate initial constraints based on view width:height ratio
        changeConstraints(view.frame.width > view.frame.height)

    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        // change active set of constraints based on view width:height ratio
        self.changeConstraints(size.width > size.height)
    }

    func changeConstraints(_ useWide: Bool) -> Void {
        if useWide {
            NSLayoutConstraint.deactivate(narrowConstraints)
            NSLayoutConstraint.activate(wideConstraints)
        } else {
            NSLayoutConstraint.deactivate(wideConstraints)
            NSLayoutConstraint.activate(narrowConstraints)
        }
    }

}

结果:

6l7fqoea

6l7fqoea2#

refer this this image for handling in device orientation
在堆栈视图中同时使用两个按钮,并使堆栈视图垂直居中,水平居中

相关问题