종횡 양방향으로 스크롤할 수 있는 뷰를 만들어 보자

18960 단어 iOSUIKitSwift

소개



세로와 가로의 양방향으로 스크롤하고 싶을 때 있어요?
그럴 때 TableViewCell에 CollectionView를 설치하여 실현할 수 있었습니다.

완성 이미지





구현 샘플



구현 절차는 다음과 같습니다.
  • 레이아웃 만들기
  • TableViewCell의 사용자 지정 클래스 정의
  • TableViewCell 중에 설치하는 CollectionView의 Cell의 커스텀 클래스를 정의한다
  • 이용 방법

  • 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의 방향을 세로 또는 옆에 지정할 수 있기 때문에
    간단하게 구현할 수 있었습니다.

    참고



    이상입니다.

    좋은 웹페이지 즐겨찾기