티스토리 뷰
[IOS AUTO LAYOUT] Dynamic Stack View
Stack | Axis | Alignment | Distribution | Spacing |
---|---|---|---|---|
Stack View | Vertical | Fill | Equal Spacing | 0 |
5 뷰컨트롤러에 커스텀뷰컨트롤러를 만들고 연결해준다
6 스크롤 뷰와 스택뷰를 커스텀뷰컨터롤러에 연결한다.
import UIKit
class DynamicStackViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var stackVIew: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
}
......
}
7 add Button을 클릭했을 때 stack view를 추가하는 코드를 작성한다.
// MARK : add Entry Methods
@IBAction func addEntry(_ sender: UIButton) {
// stack view에 있는 add button을 가져온다.
guard let addButtonContainerView = stackVIew.arrangedSubviews.last else {
fatalError("Expected at least one arranged view in the stack view")
}
// add button 한 칸 앞 index를 가져 온다
let nextEntryIndex = stackVIew.arrangedSubviews.count - 1
// scrollview의 스크롤이 이동할 위치계산
// 현 위치에서 add button의 높이 만큼 이레러
let offset = CGPoint(x: scrollView.contentOffset.x, y:
scrollView.contentOffset.y + addButtonContainerView.bounds.size.height)
// stackview를 만들어서 안 보이게 처리
let newEntryView = createEntryView()
newEntryView.isHidden = true
// 만들어진 stack view를 add button앞에다가 추가
stackVIew.insertArrangedSubview(newEntryView, at: nextEntryIndex)
// 0.25초 동안 추가된 뷰가 보이게 하면서 scrollview의 스크롤 이동
UIView.animate(withDuration: 0.25) {
newEntryView.isHidden = false
self.scrollView.contentOffset = offset
}
}
8 Delete button을 클릭했을 때 stack view를 제거하는 코드를 작성한다.
// 액션을 코드로 추가해줘야 하기 때문에 @objc를 붙여줌
@objc func deleteStackView(sender: UIButton) {
// 클릭 했을 때 버튼의 슈퍼뷰, 즉 버튼이 속해있는 stack view를 가지고 온다
guard let entryView = sender.superview else { return }
// 0.25동안 그 스택뷰를 안 보이게 하고
// 완료하면 view 계층구조에서 제거한다
// view 계층구조에서 제거하면 stackviewe에 arragedSubview에서도 자동적으로 제거됨
UIView.animate(withDuration: 0.25, animations: {
entryView.isHidden = true
}, completion: { _ in
entryView.removeFromSuperview()
})
}
9 스택뷰를 만드는 createEntryView함수를 만든다.
// 수직 스택뷰 안에 들어갈 수평 스택뷰들 만든다.
private func createEntryView() -> UIView {
// 현재날 짜는 짧게(M/D/Y) 가져온다
let date = DateFormatter.localizedString(from: Date(), dateStyle: .short, timeStyle: .none)
// uuid를 가져온다
let number = NSUUID().uuidString
// 스택뷰를 만들고
// 각 속성을 아래와 같이 한다.
// IB에서 하는 것과 같다
let stack = UIStackView()
stack.axis = .horizontal
stack.alignment = .center
stack.distribution = .fill
stack.spacing = 8
// 날짜르 표시해줄 Label를 만든다
let dateLabel = UILabel()
dateLabel.text = date
dateLabel.font = UIFont.preferredFont(forTextStyle: .body)
// uuid를 만들 Label을 만든다
let numberLabel = UILabel()
numberLabel.text = number
numberLabel.font = UIFont.preferredFont(forTextStyle: .headline)
// 이 label의 horizontal contenthugging을 249, compressionResistance 749로 해서 stackview의 남은 공간을 꽉 채우게 한다.
numberLabel.setContentHuggingPriority(UILayoutPriority.defaultLow - 1.0, for: .horizontal)
numberLabel.setContentCompressionResistancePriority(UILayoutPriority.defaultHigh - 1.0, for: .horizontal)
// 삭제 버튼을 만든다
let deleteButton = UIButton(type: .roundedRect)
deleteButton.setTitle("Delete", for: .normal)
// 삭제버튼이 눌렸다가 떨어질 때 deleteStackView를 호출하게끔 연결한다.
deleteButton.addTarget(self, action: #selector(deleteStackView(sender:)), for: .touchUpInside)
//stack 뷰에 차례대로 쌓는다.
stack.addArrangedSubview(dateLabel)
stack.addArrangedSubview(numberLabel)
stack.addArrangedSubview(deleteButton)
return stack
}
- 여기까지 런타임에 스택뷰를 만들고 추가 삭제 하는 것을 했다.
- 추가적으로 알아야 할 것
- stack view에 하위뷰를 hidden시키면 안보이긴 하지만 여전히 스택뷰에 존재한다. 다른 뷰 레이아웃에 영향을 주지 않는다.
- stack view에 하위뷰를 추가시키면 자동적으로 view hierarchy에 추가 된다
- removeArragedSubview(view:)를 통해서 하위뷰를 삭제하면 자동적으로 (view hierarchy에서 삭제가 안 된다 하지만 - removeFromSuperview를 통해서 뷰를 view hierarchy에서 제거하면 arranged views에서 삭제 된다
- 결과
'iOS' 카테고리의 다른 글
[iOS 오토레이아웃 simple constraints] Adaptive single view (0) | 2018.07.27 |
---|---|
[iOS Autolayout simple constraints] simple single view (0) | 2018.07.26 |
[IOS AUTOLAYOUT] Nested Stack Views (0) | 2018.07.14 |
[ios autolayout] simple stackview (0) | 2018.07.11 |
[ios autolayout ]What is the StackView (0) | 2018.07.05 |