我正在尝试复制Apple的计算器UI布局。
这是我到目前为止的GIF。
我遇到的问题主要与Uilables有关。从上面的GIF中可以看出,我正在遇到以下问题:
-
在设备旋转上,标签" L1"one_answers" L2"流行,而不是顺利过渡。
-
过渡回肖像时,棕色按钮上的标签消失了。
对于标签" L1"one_answers" L2",我尝试尝试使用内容模式和约束,但是,我仍然得到笨拙的过渡。
至于消失的标签,而不是隐藏/未放置堆栈视图以使布局出现并通过其隐藏属性消失,而是尝试使用堆栈视图上的约束来处理过渡,但是,结果仍然是相同。
我也在网上看并尝试了一些建议,但是,大多数答案已经过时或根本不起作用。
代码非常简单,它主要包括设置视图及其约束。
extension UIStackView {
convenience init(axis: UILayoutConstraintAxis, distribution: UIStackViewDistribution = .fill) {
self.init()
self.axis = axis
self.distribution = distribution
self.translatesAutoresizingMaskIntoConstraints = false
}
}
class Example: UIView {
let mainStackView = UIStackView(axis: .vertical, distribution: .fill)
let subStackView = UIStackView(axis: .horizontal, distribution: .fillProportionally)
let portraitStackView = UIStackView(axis: .vertical, distribution: .fillEqually)
let landscapeStackView = UIStackView(axis: .vertical, distribution: .fillEqually)
var containerView: UIView = {
$0.backgroundColor = .darkGray
$0.translatesAutoresizingMaskIntoConstraints = false
return $0
}(UIView(frame: .zero))
let mainView: UIView = {
$0.backgroundColor = .blue
$0.translatesAutoresizingMaskIntoConstraints = false
return $0
}(UIView(frame: .zero))
let labelView: UIView = {
$0.backgroundColor = .red
$0.translatesAutoresizingMaskIntoConstraints = false
return $0
}(UIView(frame: .zero))
var labelOne: UILabel!
var labelTwo: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .red
autoresizingMask = [.flexibleWidth, .flexibleHeight]
labelOne = createLabel(text: "L1")
labelOne.translatesAutoresizingMaskIntoConstraints = false
labelOne.backgroundColor = .darkGray
labelTwo = createLabel(text: "L2")
labelTwo.translatesAutoresizingMaskIntoConstraints = false
labelTwo.backgroundColor = .black
landscapeStackView.isHidden = true
mainView.addSubview(labelView)
labelView.addSubview(labelOne)
labelView.addSubview(labelTwo)
addSubview(mainStackView)
mainStackView.addArrangedSubview(mainView)
setButtonStackView()
setStackViewConstriants()
setDisplayViewConstriants()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setStackViewConstriants() {
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
mainStackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
func setDisplayViewConstriants() {
mainView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 288/667).isActive = true
labelView.heightAnchor.constraint(equalTo: mainView.heightAnchor, multiplier: 128/288).isActive = true
labelView.centerYAnchor.constraint(equalTo: mainView.centerYAnchor).isActive = true
labelView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor, constant: 24).isActive = true
labelView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor, constant: -24).isActive = true
labelOne.heightAnchor.constraint(equalTo: labelTwo.heightAnchor, multiplier: 88/32).isActive = true
labelOne.trailingAnchor.constraint(equalTo: labelView.trailingAnchor).isActive = true
labelOne.leadingAnchor.constraint(equalTo: labelView.leadingAnchor).isActive = true
labelOne.topAnchor.constraint(equalTo: labelView.topAnchor).isActive = true
labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor).isActive = true
labelTwo.trailingAnchor.constraint(equalTo: labelView.trailingAnchor).isActive = true
labelTwo.leadingAnchor.constraint(equalTo: labelOne.leadingAnchor).isActive = true
labelTwo.bottomAnchor.constraint(equalTo: labelView.bottomAnchor).isActive = true
}
func createLabel(text: String) -> UILabel {
let label = UILabel(frame: .zero)
label.text = text
label.font = UIFont.init(name: "Arial-BoldMT", size: 60)
label.textColor = .white
label.textAlignment = .right
label.contentMode = .right
label.minimumScaleFactor = 0.1
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
return label
}
func createButton(text: String) -> UIButton {
let button = UIButton(type: .custom)
button.setTitle(text, for: .normal)
button.setTitleColor(.white, for: .normal)
button.layer.borderColor = UIColor.white.cgColor
button.layer.borderWidth = 1
button.titleLabel?.font = UIFont.init(name: "Arial-BoldMT", size: 60)
button.titleLabel?.minimumScaleFactor = 0.1
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.leadingAnchor.constraint(equalTo: button.leadingAnchor).isActive = true
button.titleLabel?.trailingAnchor.constraint(equalTo: button.trailingAnchor).isActive = true
button.titleLabel?.topAnchor.constraint(equalTo: button.topAnchor).isActive = true
button.titleLabel?.bottomAnchor.constraint(equalTo: button.bottomAnchor).isActive = true
button.titleLabel?.textAlignment = .center
button.titleLabel?.contentMode = .scaleAspectFill
button.titleLabel?.numberOfLines = 0
return button
}
func setButtonStackView() {
for _ in 1...5 {
let stackView = UIStackView(axis: .horizontal, distribution: .fillEqually)
for _ in 1...4 {
let button = createButton(text: "0")
button.backgroundColor = .brown
stackView.addArrangedSubview(button)
}
landscapeStackView.addArrangedSubview(stackView)
}
for _ in 1...5 {
let stackView = UIStackView(axis: .horizontal, distribution: .fillEqually)
for _ in 1...4 {
let button = createButton(text: "0")
button.backgroundColor = .purple
stackView.addArrangedSubview(button)
}
portraitStackView.addArrangedSubview(stackView)
}
subStackView.addArrangedSubview(landscapeStackView)
subStackView.addArrangedSubview(portraitStackView)
mainStackView.addArrangedSubview(subStackView)
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
if UIDevice.current.orientation.isLandscape && landscapeStackView.isHidden == true {
self.landscapeStackView.isHidden = false
}
if UIDevice.current.orientation.isPortrait && landscapeStackView.isHidden == false {
self.landscapeStackView.isHidden = true
}
self.layoutIfNeeded()
}
}
概述:
- 使用单独的组件/视图控制器(易于调试)逐渐做事
- 以下解决方案仅适用于标签L1和L2。
- 对于计算器按钮,最好使用
UICollectionViewController
。(我尚未实现它,添加为子查看控制器)
代码:
private func setupLabels() {
view.backgroundColor = .red
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20).isActive = true
let label1 = UILabel()
label1.text = "L1"
label1.textColor = .white
label1.backgroundColor = .darkGray
label1.textAlignment = .right
label1.font = UIFont.preferredFont(forTextStyle: .title1)
let label2 = UILabel()
label2.text = "L2"
label2.textColor = .white
label2.backgroundColor = .black
label2.textAlignment = .right
label2.font = UIFont.preferredFont(forTextStyle: .caption1)
stackView.addArrangedSubview(label1)
stackView.addArrangedSubview(label2)
}