2015/08/13

Swift UIPickerViewで選択した箇所の背景色など、UIを変更する(ピッカーのカスタム)

picker.gif

Pickerの各行のラベルをカスタム

選択状態となった際に、viewForRowデリゲートメソッドにて、背景用のラベルの背景色を変更する。
下記はあくまでサンプルなので、UILabelのサブクラス作成ですっきりさせた方がよい。

//
//  ViewController.swift
//  pickerTest
//
//  Created by matz on 2015/08/13.
//  Copyright (c) 2015年 matz. All rights reserved.
//

import UIKit

final class ViewController: UIViewController,
    UIPickerViewDataSource,UIPickerViewDelegate
{

    @IBOutlet weak var picker: UIPickerView!
    private var preSelectedLb:UILabel!
    private let prefectures: NSArray =
    ["北海道","青森県","岩手県","宮城県","秋田県","山形県","福島県","茨城県","栃木県","群馬県","埼玉県","千葉県","東京都","神奈川県","新潟県","富山県","石川県","福井県","山梨県","長野県","岐阜県","静岡県","愛知県","三重県","滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","鳥取県","島根県","岡山県","広島県","山口県","徳島県","香川県","愛媛県","高知県","福岡県","佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県"
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        picker.delegate = self
        picker.dataSource = self
        // 初期選択させるのであれば
//        self.preSelectedLb = picker.viewForRow(0, forComponent: 0) as! UILabel
    }

    // 列数
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }

    // 行数
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return prefectures.count
    }

    // pickerに表示するUIViewを返す
    func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {

        let pickerLabel = UILabel()
        let titleData = prefectures[row] as! String
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "HiraKakuProN-W3", size: 20.0)!,NSForegroundColorAttributeName:UIColor.grayColor()])

        // fontサイズ、テキスト
        pickerLabel.attributedText = myTitle
        // 中央寄せ ※これを指定しないとセンターにならない
        pickerLabel.textAlignment = NSTextAlignment.Center
        pickerLabel.frame = CGRectMake(0, 0, 200, 30)
        // ラベルを角丸に
        pickerLabel.layer.masksToBounds = true
        pickerLabel.layer.cornerRadius = 5.0

        // 既存ラベル、選択状態のラベルが存在している
       if let lb = pickerView.viewForRow(row, forComponent: component) as? UILabel,
            let selected = self.preSelectedLb {
            // 設定
            self.preSelectedLb = lb
            self.preSelectedLb.backgroundColor = UIColor.orangeColor()
            self.preSelectedLb.textColor = UIColor.whiteColor()
        }

        return pickerLabel
    }


    // pickerに表示する値を返す ※viewForRowがあればこちらは単純にタイトルを返すだけなので不要
//    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
//        return prefectures[row] as! String
//    }


    // pickerが選択された際に呼ばれる
    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        println("row: \(row)")
        println("value: \(prefectures[row])")

        // 選択状態のラベルを代入
        self.preSelectedLb = pickerView.viewForRow(row, forComponent: component) as! UILabel
        // ピッカーのリロードでviewForRowが呼ばれる
        pickerView.reloadComponent(component)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

参考