如何在自动布局编程中快速减少代码行数?
这个问题不是关于如何以编程方式编写自动布局,而是要减少相关代码的长度。
下面是我与自动布局相关的代码。如您所见,它很长。我的目标是减少代码行数并避免重复。
private func buildConstraints(){
scrollview.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionTextView.translatesAutoresizingMaskIntoConstraints = false
amountLabel.translatesAutoresizingMaskIntoConstraints = false
amountTextField.translatesAutoresizingMaskIntoConstraints = false
currencyLabel.translatesAutoresizingMaskIntoConstraints = false
currencyTextField.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollview.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
scrollview.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
scrollview.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
scrollview.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
])
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: scrollview.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollview.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollview.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollview.bottomAnchor),
contentView.widthAnchor.constraint(equalTo: scrollview.widthAnchor)
])
NSLayoutConstraint.activate([
descriptionLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: SpentAmountViewOffset.top),
descriptionLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
descriptionLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
descriptionLabel.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height)
])
NSLayoutConstraint.activate([
descriptionTextView.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
descriptionTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
descriptionTextView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
descriptionTextView.heightAnchor.constraint(equalToConstant: 200)
])
NSLayoutConstraint.activate([
amountLabel.topAnchor.constraint(equalTo: descriptionTextView.bottomAnchor, constant: SpentAmountViewOffset.top),
amountLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
amountLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
amountLabel.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height)
])
NSLayoutConstraint.activate([
amountTextField.topAnchor.constraint(equalTo: amountLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
amountTextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
amountTextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
amountTextField.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height)
])
NSLayoutConstraint.activate([
currencyLabel.topAnchor.constraint(equalTo: amountTextField.bottomAnchor, constant: SpentAmountViewOffset.top),
currencyLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
currencyLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
currencyLabel.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height)
])
NSLayoutConstraint.activate([
currencyTextField.topAnchor.constraint(equalTo: currencyLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
currencyTextField.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
currencyTextField.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
currencyTextField.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height),
currencyTextField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: SpentAmountViewOffset.bottom)
])
}
有几种方法可以减少行数/重复行数。
例如,使用带有.forEach
的数组来执行相同的任务:
// all subviews need translatesAutoresizingMaskIntoConstraints = false
[scrollview, contentView, descriptionLabel, descriptionTextView, amountLabel, amountTextField, currencyLabel, currencyTextField].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
}
和:
// these subviews all have the same leading, trailing and height constraints
[descriptionLabel, amountLabel, amountTextField, currencyLabel, currencyTextField].forEach {
NSLayoutConstraint.activate([
$0.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
$0.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
$0.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height)
])
}
// descriptionTextView has same leading and trailing constraints, but different height
[descriptionTextView].forEach {
NSLayoutConstraint.activate([
$0.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: SpentAmountViewOffset.leading),
$0.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: SpentAmountViewOffset.trailing),
$0.heightAnchor.constraint(equalToConstant: 200.0)
])
}
// top / vertical spacing / bottom constraints for contentView subviews
NSLayoutConstraint.activate([
descriptionLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: SpentAmountViewOffset.top),
descriptionTextView.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
amountLabel.topAnchor.constraint(equalTo: descriptionTextView.bottomAnchor, constant: SpentAmountViewOffset.top),
amountTextField.topAnchor.constraint(equalTo: amountLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
currencyLabel.topAnchor.constraint(equalTo: amountTextField.bottomAnchor, constant: SpentAmountViewOffset.top),
currencyTextField.topAnchor.constraint(equalTo: currencyLabel.bottomAnchor, constant: SpentAmountViewOffset.top),
currencyTextField.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: SpentAmountViewOffset.bottom)
])
另一种选择是使用UIStackView
,因此您只需要对堆栈视图应用前导,尾随,顶部和底部约束:
// add subviews to stack view
[descriptionLabel, descriptionTextView, amountLabel, amountTextField, currencyLabel, currencyTextField].forEach {
stackView.addArrangedSubview($0)
}
// height constraint is the same for these views
[descriptionLabel, amountLabel, amountTextField, currencyLabel, currencyTextField].forEach {
$0.heightAnchor.constraint(equalToConstant: SpentAmountViewOffset.height).isActive = true
}
// different height constraint for descriptionTextView
descriptionTextView.heightAnchor.constraint(equalToConstant: 200.0).isActive = true
// set stackView spacing (vertical space between arranged subviews)
stackView.spacing = SpentAmountViewOffset.top
并且,如果这些是滚动视图中所有的元素,则堆栈视图可以代替“ contentView”。