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
- uiscrollview
- Clean Code
- swiftUI
- collectionview
- combine
- swift documentation
- 클린 코드
- clean architecture
- tableView
- ios
- Protocol
- uitableview
- ribs
- 리펙터링
- Observable
- UITextView
- Human interface guide
- map
- UICollectionView
- SWIFT
- RxCocoa
- 리팩토링
- HIG
- 스위프트
- rxswift
- 애니메이션
- Refactoring
- Xcode
- MVVM
- 리펙토링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UIScrollView와 UIStackView로 UITableView, UICollectionView 처럼 구현 방법 (뷰의 tag, 수평 스크롤 뷰) 본문
UI 컴포넌트 (swift)
[iOS - swift] UIScrollView와 UIStackView로 UITableView, UICollectionView 처럼 구현 방법 (뷰의 tag, 수평 스크롤 뷰)
jake-kim 2023. 2. 2. 22:23
구현 아이디어
- Cell의 UI가 복잡하거나 여러가지의 타입이 있는 경우 보통 UITableView나 UICollectionView를 사용하지만, 위처럼 단순한 수평 스크롤 뷰는 UIScrollView와 UIStackView로 쉽게 구현 가능
- 주의할점은 UITableView, UICollectionView는 Cell을 재사용하여 UI성능에 이점이 있으므로, 데이터가 많을때는 UITableView나 UICollectionView를 사용
- 구현 핵심 부분은 데이터를 선택했을때 해당 데이터의 index를 알아내는 것인데, 이것또한 UIView의 tag를 활용하면 쉽게 구현이 가능
구현
* UI를 코드로 구현할 때 편의를 위해 아래 라이브러리 사용
pod 'SnapKit'
pod 'Then'
- 수평 스크롤 뷰인 MyView 구현
import UIKit
import Then
import SnapKit
final class MyView: UIView {
}
- 필요한 UI 선언
private let scrollView = UIScrollView()
private let stackView = UIStackView().then {
$0.axis = .horizontal
$0.spacing = 12
}
- 필요한 프로퍼티 선언
- items: 외부에서 데이터를 주입하면 그만큼 UIButton을 만들어서 stackView에 사용될 데이터
- buttons: 스택뷰에 들어갈 데이터며, 저장하고 있다가 아래 selectedIndex에서 이전 버튼은 isSelected를 false로 하고 현재 선택된 버튼에는 isSelected = true로 하기 위해 선언
var items = [String]() {
didSet { setUpData() }
}
private var buttons = [UIButton]()
private var selectedIndex: Int? {
didSet {
guard let selectedIndex else { return }
if let oldValue {
buttons[oldValue].isSelected = false
}
buttons[selectedIndex].isSelected = true
}
}
- 최고화 부분
init() {
super.init(frame: .zero)
setUp()
}
required init?(coder: NSCoder) {
fatalError()
}
- autolayout
- 수평 스크롤뷰이기 때문에 stackView의 height도 고정
private func setUp() {
addSubview(scrollView)
scrollView.addSubview(stackView)
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
stackView.snp.makeConstraints {
$0.edges.height.equalToSuperview()
}
}
- 핵심부분인 setUpData() 구현
- observer property인 items값이 변경되면 호출되는 메소드
var items = [String]() {
didSet { setUpData() }
}
private func setUpData() {
// 구현
}
- items이 중복으로 입력될 수 있으므로, 구현에 앞서서 clearData() 메소드 호출
- 핵심 코드는 UIButton의 tag값을 입력해주는것
private func setUpData() {
clearData()
items
.enumerated()
.map { index, title in
let button = UIButton()
button.setTitle(title, for: .normal)
button.setTitleColor(.lightGray, for: .normal)
button.setTitleColor(.blue, for: .highlighted)
button.setTitleColor(.systemBlue, for: .selected)
button.addTarget(self, action: #selector(tapButton), for: .touchUpInside)
button.tag = index
buttons.append(button)
return button
}
.forEach(stackView.addArrangedSubview)
}
private func clearData() {
buttons.forEach { $0.removeFromSuperview() }
}
- 버튼이 눌렸을 때 tag를 활용하여 selectedIndex에 값 입력
@objc private func tapButton(_ sender: UIButton) {
print(sender.tag)
selectedIndex = sender.tag
}
- 위에서 선언했던 selectedIndex에서 이전 button과 새로 선택된 버튼을 찾아서 isSelected 반영
private var selectedIndex: Int? {
didSet {
guard let selectedIndex else { return }
if let oldValue {
buttons[oldValue].isSelected = false
}
buttons[selectedIndex].isSelected = true
}
}
(완료)
* 전체 코드: https://github.com/JK0369/ExScroll
'UI 컴포넌트 (swift)' 카테고리의 다른 글
Comments