Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Observable
- ios
- UICollectionView
- clean architecture
- ribs
- Clean Code
- collectionview
- swiftUI
- 리팩토링
- 스위프트
- rxswift
- HIG
- combine
- Refactoring
- Xcode
- Human interface guide
- map
- MVVM
- swift documentation
- Protocol
- uiscrollview
- 클린 코드
- 리펙터링
- 애니메이션
- RxCocoa
- SWIFT
- tableView
- uitableview
- UITextView
- 리펙토링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 2. Sticky Header 구현 - 스크롤 시 상단에 뷰 붙이는 방법 본문
1. Sticky Header 구현 - 스크롤 시 상단 해더 숨기는 방법
2. Sticky Header 구현 - 스크롤 시 상단에 뷰 붙이는 방법
구현 아이디어
- sticky할 뷰와 동일한 형태 뷰 준비 + 숨김 상태로 초기화
- sticky 뷰는 scroll 안에 넣지 않고 맨 상단에 보이도록 scrollView보다 위에 있도록 addSubview
- scrollView의 top은 topView의 하단에 붙이기 (topView의 하단에 sticky도 붙일것)
- sticky 뷰는 topView하단에 붙이기 + stikcy의 높이는 sticky할 뷰의 높이와 동일하게 설정
- 스크롤 뷰의 델리게이트 메소드인 scrollViewDidScroll에서 stikcy 타이밍을 계산하여 stikcyHeaderView를 hide/show
구현
* 예제에는 코드로 오토레이아웃 정의에 편리한 SnapKit 사용
- Sticky가 없는 기본 뷰 구현
- 크게 topView와 scrollView가 있고, 스크롤 되는것을 테스트하기위해 scrollView안에 stackView를 넣은 후 구현
import UIKit
import SnapKit
class ViewController: UIViewController {
private let topView: UIView = {
let view = UIView()
view.backgroundColor = .gray
return view
}()
private let scrollView: UIScrollView = {
let view = UIScrollView()
return view
}()
private let stackView: UIStackView = {
let view = UIStackView()
view.axis = .vertical
return view
}()
private let headerView: UIView = {
let view = UIView()
view.backgroundColor = .green
return view
}()
private let label1: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.text = "long text \n\n text \n\n\n text \n\n text \n text \n\n\n texttexttext"
label.textColor = .black
return label
}()
private let label2: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.text = "long text \n\n text \n\n\n text \n\n text \n text \n\n\n texttexttext \n\n\n\n text \n\n\n\n\n\n\n text \n\n\n\n\n\n\n\n\n\n text \n\n\n\n \n\n\n\n \n\n\n\n \n\n\n\n text"
label.textColor = .black
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(topView)
view.addSubview(scrollView)
scrollView.addSubview(stackView)
stackView.addArrangedSubview(label1)
stackView.addArrangedSubview(headerView)
stackView.addArrangedSubview(label2)
topView.snp.makeConstraints {
$0.top.left.right.equalToSuperview()
$0.height.equalTo(120)
}
scrollView.snp.makeConstraints {
$0.top.equalTo(topView.snp.bottom)
$0.left.bottom.right.equalToSuperview()
}
stackView.snp.makeConstraints {
$0.edges.width.equalToSuperview()
}
headerView.snp.makeConstraints {
$0.height.equalTo(56)
}
}
}
- stikcy할 뷰와 동일한 형태의 뷰 준비
// 1. sticky할 뷰와 동일한 형태 뷰 준비 + 숨김 상태로 초기화
private let stickyHeaderView: UIView = {
let view = UIView()
view.backgroundColor = .green
view.isHidden = true
return view
}()
- sticky 뷰 삽입
// 2. sticky 뷰는 scroll 안에 넣지 않고 맨 상단에 보이도록 scrollView보다 위에 삽입
view.addSubview(stickyHeaderView)
- 스크롤뷰의 top이 어디에 있는지 확인 후, sticky뷰의 top도 동일하게 붙이기
// 3. scrollView의 top은 topView의 하단에 붙이기 (topView의 하단에 sticky도 붙일것)
scrollView.snp.makeConstraints {
$0.top.equalTo(topView.snp.bottom)
$0.left.bottom.right.equalToSuperview()
}
// 4. sticky 뷰는 topView하단에 붙이기 + stikcy의 높이는 sticky할 뷰의 높이와 동일하게 설정
stickyHeaderView.snp.makeConstraints {
$0.top.equalTo(topView.snp.bottom)
$0.left.right.equalToSuperview()
$0.height.equalTo(56)
}
- scrollViewDidScroll 델리게이트에서 stikcy를 언제 hide/show 할지 판단
- 핵심) sticky할 뷰의 frame.minY와 contentOffset.y를 구분하면 쉽게 파악이 가능
scrollView.delegate = self
...
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// contentOffset.y: 손가락을 위로 올리면 + 값, 손가락을 아래로 내리면 - 값
print(scrollView.contentOffset.y, headerView.frame.minY)
// 5. 핵심 - frame.minY를 통해 sticky 타이밍을 계산
let shouldShowSticky = scrollView.contentOffset.y >= headerView.frame.minY
stickyHeaderView.isHidden = !shouldShowSticky
}
}
'UI 컴포넌트 (swift)' 카테고리의 다른 글
Comments