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 |
Tags
- tableView
- 리펙토링
- 스위프트
- 클린 코드
- UITextView
- 리펙터링
- Clean Code
- ios
- rxswift
- clean architecture
- map
- SWIFT
- Human interface guide
- MVVM
- HIG
- combine
- Xcode
- 리팩토링
- Protocol
- swift documentation
- collectionview
- swiftUI
- 애니메이션
- Observable
- RxCocoa
- uitableview
- uiscrollview
- ribs
- UICollectionView
- Refactoring
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 가로 슬라이드 뷰 (SliderCollectionView) 구현 본문
SliderCollectionView
- Grid모양의 CollectionView에서 해당 셀을 선택하면, 해당하는 셀에 대한 정보를 두 번째 ViewController에 넘기고, SliderCollectionView로 정보를 표출
편리함을 위해서 사용한 프레임워크 사용방법 참고
SliderCollectionView 구현 핵심
- 화면: ImageViewController(Grid형태의 CollectionView) -> DetailViewController(Slider형태의 CollectionView)
- 첫 번째 Grid 형태의 CollectionView가 있는 ImageViewController에서 Cell을 탭하면 해당하는 Cell의 정보를 두 번째 ViewController에게 넘기고 여기서 SliderCollectionView 표출
- 커스텀 CollectionViewCell은 단순히 ImageView가 있고, contentMode는 scaleAspectFill로하고 clipsToBounds를 on한 상태
// SliderCollectionViewCell.swift import UIKit import Reusable import SnapKit final class SliderCollectionViewCell: UICollectionViewCell, Reusable { // MARK: UI private let photoImageView = UIImageView().then { $0.contentMode = .scaleAspectFill $0.clipsToBounds = true } // MARK: Initializers override init(frame: CGRect) { super.init(frame: frame) self.contentView.addSubview(self.photoImageView) self.photoImageView.snp.makeConstraints { $0.edges.equalToSuperview() } } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setImage(_ image: UIImage) { photoImageView.image = image } }
- SliderCollectionView는 scrollDirection 값을 horizontal로 부여
// DetailViewController.swift // MARK: UI private let sliderCollectionView = UICollectionView( frame: .zero, collectionViewLayout: UICollectionViewFlowLayout().then { $0.minimumLineSpacing = Metric.collectionViewSpacing $0.minimumInteritemSpacing = Metric.collectionViewSpacing $0.scrollDirection = .horizontal // <- 여기 } ).then { $0.register(cellType: SliderCollectionViewCell.self) $0.contentInset = Metric.collectionViewContentInset $0.showsHorizontalScrollIndicator = false $0.allowsSelection = true $0.isScrollEnabled = true $0.bounces = true $0.backgroundColor = Color.clear $0.isPagingEnabled = true }
- autolayout
// DetailViewController.swift private func configureLayout() { view.addSubview(self.sliderCollectionView) self.sliderCollectionView.snp.makeConstraints { $0.centerX.centerY.equalToSuperview() $0.height.equalTo(view.safeAreaLayoutGuide).inset(Metric.collectionViewVerticalInset) $0.left.right.equalTo(view.safeAreaLayoutGuide).inset(Metric.collectionViewHorizontalInset) } }
- CollectionView에 이미지들을 가로로 나열하기 위해서 item들의 size들을 collectionView와 동일하게 설정
- UICollectionViewDeelgateFlowLayout 델리게이트에서 sizeForItemAt 델리게이트 메소드 사용
// DetailViewController.swift // Delegate 준수 self.sliderCollectionView.rx.setDelegate(self) .disposed(by: self.disposeBag) // Delegate 구현 extension DetailViewController: UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let widthPadding = Metric.collectionViewSpacing let width = sliderCollectionView.bounds.size.width - widthPadding let height = sliderCollectionView.bounds.size.height return CGSize(width: width, height: height) } }
- UICollectionViewDeelgateFlowLayout 델리게이트에서 sizeForItemAt 델리게이트 메소드 사용
- 디바이스 가로, 세로 회전 대응
- 기존에 vertical inset의 크기가 screen의 1/3로 잡혀 있었으므로 디바이스가 회전하여 가로모드가 되면 크기가 찌부되는 현상(UI 미표출) 발생
- 가로모드인 경우에는 vertical inset의 크기를 작게하는 코드 필요
// exetnsion으로 추가
public extension Reactive where Base: UIViewController {
var viewWillTransition: ControlEvent<Void> {
let source = self.methodInvoked(#selector(Base.viewWillTransition)).map { _ in }
return ControlEvent(events: source)
}
}
// bind
self.rx.viewWillTransition
.bind { [weak self] in self?.updateConstraints() }
.disposed(by: disposeBag)
// update constraints
private func updateConstraints() {
let isPortrait = UIDevice.current.orientation.isPortrait
let verticalInset = isPortrait
? Metric.collectionViewVerticalInset
: Metric.collectionViewHorizontalInset
self.sliderCollectionView.snp.updateConstraints {
$0.height.equalTo(view.safeAreaLayoutGuide).inset(verticalInset)
}
}
* 전체 소스 코드: https://github.com/JK0369/ExPhotoSlider
'UI 컴포넌트 (swift)' 카테고리의 다른 글
Comments