読者です 読者をやめる 読者になる 読者になる

UIScrollVIewとUICollectionViewでアイコンやラベルが横スクロールする画面を作る方法

はじめに

需要あるかわからないけどやる機会があったのでつくり方をメモしておきます。
また、きっともっと簡単に実現する方法があると思うのでそういうのあったらアドバイスいただきたいです

やりたいのは以下のように、アイコンやラベルを横並びにして画面に収まりきらない分はスクロールしてみれるありがちなUIです

画面イメージ
f:id:yoppy0066:20150422024859p:plain
f:id:yoppy0066:20150422024907p:plain
わかりずらいんですけど、スクロールするとその部分だけスライドするみたいなかんじです

実装

ViewController.swift

class ViewController: UIViewController {

    var scrollView: UIScrollView!
    
    var items = [
        ["テスト1", "テスト2", "テスト3"],
        ["テスト11", "テスト22", "テスト33"],
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        // スクロールView高さ
        let heightScroll: CGFloat = 80

        // スクロールView
        scrollView = UIScrollView(frame: CGRect(x:0, y:heightScroll, width:self.view.frame.width, height:heightScroll))
        scrollView.pagingEnabled = true
        
        // サブView
        for var i=0; i<items.count; i++ {
            var subView = CustomView(frame: CGRect(x: CGFloat(i) * scrollView.frame.width, y: 0, width: scrollView.frame.width, height: scrollView.frame.height))
            subView.items = items[i]
            scrollView.addSubview(subView)
        }
        
        scrollView.contentSize = CGSizeMake(self.view.frame.width * 4, heightScroll)
        self.view.addSubview(scrollView)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

CustomView.swift

// スクロールさせるView
class CustomView :UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
//class CustomView :UIView
{
    var items: [AnyObject]!
    var labelTitle: UILabel!
    var collectionView: UICollectionView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setUp()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setUp()
    }
    
    func setUp() {
        collectionView = UICollectionView(frame: CGRect(x:0, y:0, width:self.frame.width, height:self.frame.height), collectionViewLayout: UICollectionViewFlowLayout())
        collectionView.registerClass(CustomUICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
        
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.backgroundColor = UIColor.clearColor()
        
        self.addSubview(collectionView)
    }
    
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell: CustomUICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
            forIndexPath: indexPath) as! CustomUICollectionViewCell
        cell.textLabel?.text = items[indexPath.row] as? String
        return cell
    }
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        
        let width: CGFloat = self.frame.width / 3 - 2
        let height: CGFloat = 60
        return CGSize(width: width, height: height) // The size of one cell
    }
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 0
    }
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return 1
    }
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        
        let frame: CGRect = self.frame
        var marginH: CGFloat = 1
        var marginV: CGFloat = 1
        return UIEdgeInsetsMake(marginV, marginH, marginV, marginH) // margin between cells
    }
}

CustomUICollectionViewCell.swift

class CustomUICollectionViewCell : UICollectionViewCell{
    var textLabel : UILabel?
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.backgroundColor = UIColor.yellowColor()

        textLabel = UILabel(frame: CGRectMake(0, 0, frame.width/2, frame.height/2))
        textLabel?.center = CGPoint(x: frame.width/2, y: frame.height/2)
        textLabel?.text = ""
        textLabel?.font = UIFont.systemFontOfSize(12)
        textLabel?.textAlignment = NSTextAlignment.Center
        textLabel?.backgroundColor = UIColor.orangeColor()
        
        self.contentView.addSubview(textLabel!)
    }
}

クラスは3つあって
ViewController.swiftはメインとなる画面
CustomView.swiftは1ページに表示させる分のView
CustomUICollectionViewCellはスクロールさせる領域の中の1セル
といった感じにしてみました。

他の人はもっとうまいことやるんだろうなぁと思いつつやってるんですけど、とりあえず期待することが実現できました

以上です