这个 StackView 有什么问题?
What is wrong with this StackView?
我的 StackView 有什么问题?
这是代码:
class PushUpViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpStackView()
}
func setUpStackView() {
// SetUp StackView:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.spacing = 50
view.addSubview(stackView)
// SetUp StackView Constraints:
stackView.pin(to: view)
stackView.setCustomSpacing(50, after: PushUpButton)
stackView.setCustomSpacing(100, after: TimeLabel)
// Set Elements to StackView:
stackView.addArrangedSubview(TimeLabel)
stackView.addArrangedSubview(PushUpButton)
stackView.addArrangedSubview(secondStackView)
// SetUp PushUpButton:
PushUpButton.backgroundColor = .white
PushUpButton.setTitle("\(count)", for: .normal)
PushUpButton.setTitleColor(.systemGray, for: .normal)
PushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
PushUpButton.translatesAutoresizingMaskIntoConstraints = false
PushUpButton.heightAnchor.constraint(equalToConstant: 300).isActive = true
PushUpButton.widthAnchor.constraint(equalToConstant: 150).isActive = true
// SetUp TimeLabel
TimeLabel.textAlignment = .center
TimeLabel.text = "\(counter)"
TimeLabel.textColor = .black
TimeLabel.font = .boldSystemFont(ofSize: 30)
self.view.addSubview(TimeLabel)
TimeLabel.translatesAutoresizingMaskIntoConstraints = false
TimeLabel.widthAnchor.constraint(equalToConstant: 300).isActive = true
TimeLabel.heightAnchor.constraint(equalToConstant: 200).isActive = true
// SetUp SecondStackView
secondStackView.translatesAutoresizingMaskIntoConstraints = false
secondStackView.axis = .horizontal
secondStackView.alignment = .center
secondStackView.distribution = .fillEqually
secondStackView.spacing = 20
// SetUp SecondStackView Constrains
secondStackView.heightAnchor.constraint(equalToConstant: 50).isActive = true
secondStackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -15).isActive = true
// Set Elements:
secondStackView.addArrangedSubview(breakButton)
secondStackView.addArrangedSubview(stopbutton)
//SetUp BreakButton
breakButton.backgroundColor = .lightGray
breakButton.setTitle("Break", for: .normal)
breakButton.setTitle("Start", for: .selected)
breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
breakButton.setTitleColor(.white, for: .normal)
breakButton.layer.cornerRadius = 12
breakButton.layer.borderWidth = 1
breakButton.layer.borderColor = UIColor.white.cgColor
// breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
breakButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
breakButton.widthAnchor.constraint(equalToConstant: 150),
breakButton.heightAnchor.constraint(equalToConstant: 50)
])
// SetUp StopButton:
stopbutton.backgroundColor = .systemRed
stopbutton.setTitle("Stop", for: .normal)
stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
stopbutton.setTitleColor(.white, for: .normal)
stopbutton.layer.cornerRadius = 12
stopbutton.layer.borderWidth = 1
stopbutton.layer.borderColor = UIColor.white.cgColor
// stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
stopbutton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stopbutton.widthAnchor.constraint(equalToConstant: 150),
stopbutton.heightAnchor.constraint(equalToConstant: 50)
])
}
}
它是这样的:
但它应该是这样的:
这是我在 StackView 上时控制台中出现的内容 VC:
我不知道这意味着什么,也不知道我应该怎么做才能解决这个问题
我不明白 StackViews...我看了很多 yt 教程,但它们都是一样的,对我没有帮助。我最大的问题是StackView的分布:我不知道区别在哪里
第一个提示:忘记对堆栈视图使用 .fillProportionally
。它几乎从未被使用过……当它被使用时,它的使用是出于非常特殊的原因。
第二个提示:在开发过程中,为您的 UI 元素提供对比背景色,以便在 运行 时轻松查看帧。
第三个提示:使用 leadingLowerCase
作为变量和函数名称...使用 LeadingUpperCase
作为 class 名称。
第四个提示:将相似的代码组合在一起 - 例如设置视图属性、设置约束等 - 并包含逻辑注释,以便更容易理解代码的作用。
看看这个:
class PushUpViewController: UIViewController {
let stackView = UIStackView()
let secondStackView = UIStackView()
let pushUpButton = UIButton()
let breakButton = UIButton()
let stopbutton = UIButton()
let timeLabel = UILabel()
var count: Int = 0
var counter: Float = 0.0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpStackView()
}
func setUpStackView() {
// SetUp StackView:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fill
// SetUp timeLabel
timeLabel.textAlignment = .center
timeLabel.text = "\(counter)"
timeLabel.textColor = .black
timeLabel.font = .boldSystemFont(ofSize: 30)
// SetUp pushUpButton:
pushUpButton.backgroundColor = .white
pushUpButton.setTitle("\(count)", for: .normal)
pushUpButton.setTitleColor(.systemGray, for: .normal)
pushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
// SetUp secondStackView
secondStackView.axis = .horizontal
secondStackView.alignment = .fill
secondStackView.distribution = .fillEqually
secondStackView.spacing = 20
//SetUp breakButton
breakButton.backgroundColor = .lightGray
breakButton.setTitle("Break", for: .normal)
breakButton.setTitle("Start", for: .selected)
breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
breakButton.setTitleColor(.white, for: .normal)
breakButton.layer.cornerRadius = 12
breakButton.layer.borderWidth = 1
breakButton.layer.borderColor = UIColor.white.cgColor
// SetUp stopButton:
stopbutton.backgroundColor = .systemRed
stopbutton.setTitle("Stop", for: .normal)
stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
stopbutton.setTitleColor(.white, for: .normal)
stopbutton.layer.cornerRadius = 12
stopbutton.layer.borderWidth = 1
stopbutton.layer.borderColor = UIColor.white.cgColor
// add buttons to horizontal second stack view
secondStackView.addArrangedSubview(breakButton)
secondStackView.addArrangedSubview(stopbutton)
// if we want the center PushUpButton to be 300 x 150
// and centered vertically
// we need to embed it in a clear view
let holderView = UIView()
// add PushUpButton to holderView
holderView.addSubview(pushUpButton)
// views added as arrangedSubviews of a stack view automatically get
// .translatesAutoresizingMaskIntoConstraints = false
// but, because we're adding the PushUpButton as a subview
// of holderView, we need to set it here
pushUpButton.translatesAutoresizingMaskIntoConstraints = false
// add views to stack view
stackView.addArrangedSubview(timeLabel)
stackView.addArrangedSubview(holderView)
stackView.addArrangedSubview(secondStackView)
// add stackView to view
view.addSubview(stackView)
// SetUp StackView Constraints:
//stackView.pin(to: view)
// respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain stackview to full view (safe-area)
// to bottom with Zero extra space
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
// to top with 20-pts "padding"
stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
// and 8-pts "padding" on each side
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
// pushUpButton should be 300x150
pushUpButton.widthAnchor.constraint(equalToConstant: 300.0),
pushUpButton.heightAnchor.constraint(equalToConstant: 150.0),
// pushUpButton should be centered in holderView
pushUpButton.centerXAnchor.constraint(equalTo: holderView.centerXAnchor),
pushUpButton.centerYAnchor.constraint(equalTo: holderView.centerYAnchor),
// bottom buttons should have Height: 50
secondStackView.heightAnchor.constraint(equalToConstant: 50.0),
])
// break and stop button actions
//breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
//stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
// during development, so we can see the layout easily
//holderView.backgroundColor = .yellow
//PushUpButton.backgroundColor = .green
//TimeLabel.backgroundColor = .cyan
}
}
iPhone11 的结果:
于 iPhone 8:
并在开发过程中提供背景颜色帮助:
附加提示:
学习自动布局(尤其是堆栈视图)时,请在 Storyboard / Interface Builder 中处理您的布局。您可以立即看到它的外观以及更改值/属性时会发生什么。您还可以更改 View as: 以立即查看它在不同设备/屏幕尺寸上的外观。如果您想将所有内容都保留在代码中,一旦您的布局看起来像您想要的那样,然后在代码中复制这些约束和设置。
我的 StackView 有什么问题? 这是代码:
class PushUpViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpStackView()
}
func setUpStackView() {
// SetUp StackView:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .center
stackView.distribution = .fillProportionally
stackView.spacing = 50
view.addSubview(stackView)
// SetUp StackView Constraints:
stackView.pin(to: view)
stackView.setCustomSpacing(50, after: PushUpButton)
stackView.setCustomSpacing(100, after: TimeLabel)
// Set Elements to StackView:
stackView.addArrangedSubview(TimeLabel)
stackView.addArrangedSubview(PushUpButton)
stackView.addArrangedSubview(secondStackView)
// SetUp PushUpButton:
PushUpButton.backgroundColor = .white
PushUpButton.setTitle("\(count)", for: .normal)
PushUpButton.setTitleColor(.systemGray, for: .normal)
PushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
PushUpButton.translatesAutoresizingMaskIntoConstraints = false
PushUpButton.heightAnchor.constraint(equalToConstant: 300).isActive = true
PushUpButton.widthAnchor.constraint(equalToConstant: 150).isActive = true
// SetUp TimeLabel
TimeLabel.textAlignment = .center
TimeLabel.text = "\(counter)"
TimeLabel.textColor = .black
TimeLabel.font = .boldSystemFont(ofSize: 30)
self.view.addSubview(TimeLabel)
TimeLabel.translatesAutoresizingMaskIntoConstraints = false
TimeLabel.widthAnchor.constraint(equalToConstant: 300).isActive = true
TimeLabel.heightAnchor.constraint(equalToConstant: 200).isActive = true
// SetUp SecondStackView
secondStackView.translatesAutoresizingMaskIntoConstraints = false
secondStackView.axis = .horizontal
secondStackView.alignment = .center
secondStackView.distribution = .fillEqually
secondStackView.spacing = 20
// SetUp SecondStackView Constrains
secondStackView.heightAnchor.constraint(equalToConstant: 50).isActive = true
secondStackView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -15).isActive = true
// Set Elements:
secondStackView.addArrangedSubview(breakButton)
secondStackView.addArrangedSubview(stopbutton)
//SetUp BreakButton
breakButton.backgroundColor = .lightGray
breakButton.setTitle("Break", for: .normal)
breakButton.setTitle("Start", for: .selected)
breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
breakButton.setTitleColor(.white, for: .normal)
breakButton.layer.cornerRadius = 12
breakButton.layer.borderWidth = 1
breakButton.layer.borderColor = UIColor.white.cgColor
// breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
breakButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
breakButton.widthAnchor.constraint(equalToConstant: 150),
breakButton.heightAnchor.constraint(equalToConstant: 50)
])
// SetUp StopButton:
stopbutton.backgroundColor = .systemRed
stopbutton.setTitle("Stop", for: .normal)
stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
stopbutton.setTitleColor(.white, for: .normal)
stopbutton.layer.cornerRadius = 12
stopbutton.layer.borderWidth = 1
stopbutton.layer.borderColor = UIColor.white.cgColor
// stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
stopbutton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stopbutton.widthAnchor.constraint(equalToConstant: 150),
stopbutton.heightAnchor.constraint(equalToConstant: 50)
])
}
}
它是这样的:
但它应该是这样的:
这是我在 StackView 上时控制台中出现的内容 VC:
我不知道这意味着什么,也不知道我应该怎么做才能解决这个问题
我不明白 StackViews...我看了很多 yt 教程,但它们都是一样的,对我没有帮助。我最大的问题是StackView的分布:我不知道区别在哪里
第一个提示:忘记对堆栈视图使用 .fillProportionally
。它几乎从未被使用过……当它被使用时,它的使用是出于非常特殊的原因。
第二个提示:在开发过程中,为您的 UI 元素提供对比背景色,以便在 运行 时轻松查看帧。
第三个提示:使用 leadingLowerCase
作为变量和函数名称...使用 LeadingUpperCase
作为 class 名称。
第四个提示:将相似的代码组合在一起 - 例如设置视图属性、设置约束等 - 并包含逻辑注释,以便更容易理解代码的作用。
看看这个:
class PushUpViewController: UIViewController {
let stackView = UIStackView()
let secondStackView = UIStackView()
let pushUpButton = UIButton()
let breakButton = UIButton()
let stopbutton = UIButton()
let timeLabel = UILabel()
var count: Int = 0
var counter: Float = 0.0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpStackView()
}
func setUpStackView() {
// SetUp StackView:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fill
// SetUp timeLabel
timeLabel.textAlignment = .center
timeLabel.text = "\(counter)"
timeLabel.textColor = .black
timeLabel.font = .boldSystemFont(ofSize: 30)
// SetUp pushUpButton:
pushUpButton.backgroundColor = .white
pushUpButton.setTitle("\(count)", for: .normal)
pushUpButton.setTitleColor(.systemGray, for: .normal)
pushUpButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 70)
// SetUp secondStackView
secondStackView.axis = .horizontal
secondStackView.alignment = .fill
secondStackView.distribution = .fillEqually
secondStackView.spacing = 20
//SetUp breakButton
breakButton.backgroundColor = .lightGray
breakButton.setTitle("Break", for: .normal)
breakButton.setTitle("Start", for: .selected)
breakButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
breakButton.setTitleColor(.white, for: .normal)
breakButton.layer.cornerRadius = 12
breakButton.layer.borderWidth = 1
breakButton.layer.borderColor = UIColor.white.cgColor
// SetUp stopButton:
stopbutton.backgroundColor = .systemRed
stopbutton.setTitle("Stop", for: .normal)
stopbutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
stopbutton.setTitleColor(.white, for: .normal)
stopbutton.layer.cornerRadius = 12
stopbutton.layer.borderWidth = 1
stopbutton.layer.borderColor = UIColor.white.cgColor
// add buttons to horizontal second stack view
secondStackView.addArrangedSubview(breakButton)
secondStackView.addArrangedSubview(stopbutton)
// if we want the center PushUpButton to be 300 x 150
// and centered vertically
// we need to embed it in a clear view
let holderView = UIView()
// add PushUpButton to holderView
holderView.addSubview(pushUpButton)
// views added as arrangedSubviews of a stack view automatically get
// .translatesAutoresizingMaskIntoConstraints = false
// but, because we're adding the PushUpButton as a subview
// of holderView, we need to set it here
pushUpButton.translatesAutoresizingMaskIntoConstraints = false
// add views to stack view
stackView.addArrangedSubview(timeLabel)
stackView.addArrangedSubview(holderView)
stackView.addArrangedSubview(secondStackView)
// add stackView to view
view.addSubview(stackView)
// SetUp StackView Constraints:
//stackView.pin(to: view)
// respect safe-area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain stackview to full view (safe-area)
// to bottom with Zero extra space
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
// to top with 20-pts "padding"
stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
// and 8-pts "padding" on each side
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
// pushUpButton should be 300x150
pushUpButton.widthAnchor.constraint(equalToConstant: 300.0),
pushUpButton.heightAnchor.constraint(equalToConstant: 150.0),
// pushUpButton should be centered in holderView
pushUpButton.centerXAnchor.constraint(equalTo: holderView.centerXAnchor),
pushUpButton.centerYAnchor.constraint(equalTo: holderView.centerYAnchor),
// bottom buttons should have Height: 50
secondStackView.heightAnchor.constraint(equalToConstant: 50.0),
])
// break and stop button actions
//breakButton.addTarget(self, action: #selector(BreakButtonTapped), for: .touchUpInside)
//stopbutton.addTarget(self, action: #selector(stopButtonTapped), for: .touchUpInside)
// during development, so we can see the layout easily
//holderView.backgroundColor = .yellow
//PushUpButton.backgroundColor = .green
//TimeLabel.backgroundColor = .cyan
}
}
iPhone11 的结果:
于 iPhone 8:
并在开发过程中提供背景颜色帮助:
附加提示:
学习自动布局(尤其是堆栈视图)时,请在 Storyboard / Interface Builder 中处理您的布局。您可以立即看到它的外观以及更改值/属性时会发生什么。您还可以更改 View as: 以立即查看它在不同设备/屏幕尺寸上的外观。如果您想将所有内容都保留在代码中,一旦您的布局看起来像您想要的那样,然后在代码中复制这些约束和设置。