종횡 양방향으로 스크롤할 수 있는 뷰를 만들어 보자
소개
세로와 가로의 양방향으로 스크롤하고 싶을 때 있어요?
그럴 때 TableViewCell에 CollectionView를 설치하여 실현할 수 있었습니다.
완성 이미지
구현 샘플
구현 절차는 다음과 같습니다.
구현 절차는 다음과 같습니다.
1. 레이아웃 만들기
레이아웃은 아래와 같은 계층 구조입니다.
포인트는 TableViewCell 내에 CollectionView를 설치하고 있다는 점입니다.
클래스 이름
설명
TableViewInCollectionViewCell
TableViewCell의 사용자 지정 클래스 이름
CollectionViewCell
TableViewCell 중에 설치하는 CollectionViewCell의 커스텀 클래스명
ViewController
화면 클래스 이름
CollectionView의 Scroll Direction은
옆으로 스크롤하기 위해 "Horizontal"을 지정합니다.
2. TableViewCell의 사용자 지정 클래스 정의
TableViewCell 내에서 가로 스크롤할 수 있도록 합니다.
또한 어떤 줄이 호출되었는지 알 수 있도록 태그에 줄 번호를 저장합니다.
TableViewInCollectionViewCell.swift
import UIKit
class TableViewInCollectionViewCell: UITableViewCell {
@IBOutlet weak var collectionView: UICollectionView!
static var identifier: String {
get {
return String(self)
}
}
}
extension TableViewInCollectionViewCell {
func setCollectionViewDataSourceDelegate<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>(
dataSourceDelegate: D, forRow row: Int) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.tag = row
collectionView.setContentOffset(collectionView.contentOffset, animated: false)
collectionView.reloadData()
}
var collectionViewOffset: CGFloat {
set {
collectionView.contentOffset.x = newValue
}
get {
return collectionView.contentOffset.x
}
}
}
3. TableViewCell 중에 설치할 CollectionView의 Cell 사용자 정의 클래스를 정의합니다.
이미지만 표시할 셀을 정의합니다.
자유롭게 사용자 정의하십시오.
CollectionViewCell
import UIKit
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
static var identifier: String {
get {
return String(self)
}
}
}
4. 이용 방법
포인트는, TableView를 표시한 타이밍에 CollectionView의 표시 및, 스크롤의 조정을 하고 있는 점입니다.
ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
let dataSource = ViewController.generateRandomData() //テストデータ
var offsets = [Int: CGFloat]()
}
extension ViewController: UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(TableViewInCollectionViewCell.identifier,
forIndexPath: indexPath)
return cell
}
}
extension ViewController: UITableViewDelegate {
//TableViewCellが表示されたときに、CollectionViewの描画する
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewInCollectionViewCell else {
return
}
tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
tableViewCell.collectionViewOffset = offsets[indexPath.row] ?? 0
}
func tableView(tableView: UITableView,
didEndDisplayingCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {
guard let tableViewCell = cell as? TableViewInCollectionViewCell else {
return
}
offsets[indexPath.row] = tableViewCell.collectionViewOffset
}
}
extension ViewController: UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return dataSource[collectionView.tag].count
}
func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CollectionViewCell.identifier,
forIndexPath: indexPath) as! CollectionViewCell
cell.imageView.image = dataSource[collectionView.tag][indexPath.item]
return cell
}
}
extension ViewController: UICollectionViewDelegate {
//タップされたときに、縦が何行目、横が何マス目か判断する
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("Line : \(collectionView.tag) / section : \(indexPath.section) / row : \(indexPath.row)")
}
}
// 画像表示用のダミーデータを取得する機能
extension ViewController {
class func randomImage() -> UIImage {
let fileNameIndex = arc4random() % 2
let fileName = "image\(fileNameIndex + 1).jpg"
return UIImage.init(named: fileName)!
}
class func generateRandomData() -> [[UIImage]] {
let numberOfRows = 15
let numberOfItemsPerRow = 10
return (0..<numberOfRows).map { _ in
return (0..<numberOfItemsPerRow).map { _ in randomImage() }
}
}
}
요약
TableViewCell 안에 TableView를 배치하는 방법도 시도했지만,
TableView와 TableViewCell의 방향을 각각 90도 회전하지 않으면,
표시되는 방향을 예상대로 표시할 수 없습니다.
그러나 CollectionView는 Scroll의 방향을 세로 또는 옆에 지정할 수 있기 때문에
간단하게 구현할 수 있었습니다.
참고
이상입니다.
Reference
이 문제에 관하여(종횡 양방향으로 스크롤할 수 있는 뷰를 만들어 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/eKushida/items/e95254f97646a816cce5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(종횡 양방향으로 스크롤할 수 있는 뷰를 만들어 보자), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/eKushida/items/e95254f97646a816cce5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)