StacView를 사용하면 contraint를 줄일 수 있다.
import UIKit
class ScrollableView: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
navigationItem.title = "Scrollable"
let stackView = makeStackView(withOrientation: .vertical)
let scrollView = makeScrollView()
scrollView.addSubview(stackView)
view.addSubview(scrollView)
for _ in 1...40 {
let row = RowView()
stackView.addArrangedSubview(row)
}
// Pinning to the sides of view
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// Pinning scrollview
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
}
}
for _ in 1...40 {
let row = RowView()
stackView.addArrangedSubview(row)
row.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
// Note: We need to adjust our width to take into account the extra padding on the side (16x2 = 32)
row.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 1, constant: -32).isActive = true
stackView.isLayoutMarginsRelativeArrangement = true
stackView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 40, leading: 16, bottom: 40, trailing: 16)
for i in 1...40 {
let row = RowView()
stackView.addArrangedSubview(row)
// Add a spacer every 5th row
if i % 5 == 0 {
stackView.addArrangedSubview(makeSpacerView(height: 200))
}
// Note: We need to adjust our width to take into account the extra padding on the side (16x2 = 32)
row.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 1, constant: -32).isActive = true
}
// Factories.Swift
public func makeSpacerView(height: CGFloat? = nil) -> UIView {
let spacerView = UIView(frame: .zero)
if let height = height {
spacerView.heightAnchor.constraint(equalToConstant: height).setActiveBreakable()
}
spacerView.translatesAutoresizingMaskIntoConstraints = false
return spacerView
}
public extension NSLayoutConstraint {
@objc func setActiveBreakable(priority: UILayoutPriority = UILayoutPriority(900)) {
self.priority = priority
isActive = true
}
}
setActiveBreakable 메소드로 constraint의 우선도를 900으로 낮춤으로써 StackView안의 공간이 부족할 경우 spacerView가 줄어든다.
소중한 정보 감사드립니다!