今からお前んちこいよ

品川にて細々とお勉強。

swift - チェック・ラジオボタンをプログラムで作る

swiftでチェックボタン・ラジオボタンを作る。プログラムで。
ここではUIButtonクラスを拡張してコードで作る。
Storyboardでやる人はそれでやればいいと思う。

作るもの

   <ラジオボタン>        <チェックボタン> f:id:hakopako03:20161013112134p:plain   f:id:hakopako03:20161013112154p:plain

使い方

// 生成
let myButton:MyCheckButton = MyCheckButton(isMulti: false, color: UIColor.purple)

// オン
myButton.on()

// オフ
myButton.off()

// 切り替え
myButton.toggle()

// 任意
myButton.baseColor = UIColor.gray

仕組み

UIButtonのviewに矩形を描画している。(それだけ

override func draw(_ rect: CGRect) {
    super.draw(rect)
    /* do something */
}

 

引数のisMultitrueならチェックボタンとして枠の四角とチェックマークを描画

if isMulti {
    // frame is rectangle
    framePath.move(to: CGPoint(x:margin, y:margin))
    framePath.addLine(to: CGPoint(x:margin, y:self.frame.height - margin))
    framePath.addLine(to: CGPoint(x:self.frame.height - margin, y:self.frame.height - margin))
    framePath.addLine(to: CGPoint(x:self.frame.height - margin, y:margin))
    framePath.addLine(to: CGPoint(x:margin - lineWidth/2, y:margin))
    framePath.stroke()
    // selected mark is v
    checkPath.move(to: CGPoint(x:margin + 2, y:self.frame.height/2 - 2))
    checkPath.addLine(to: CGPoint(x:self.frame.height/2, y:self.frame.height/2 + 2))
    checkPath.addLine(to: CGPoint(x:self.frame.height - margin + 2, y:margin - 2))
    checkPath.stroke(with: CGBlendMode.clear, alpha: 0)
    checkShapeLayer.strokeColor = tintColor.cgColor
    checkShapeLayer.fillColor = UIColor.clear.cgColor
} 

 
isMultifalseならラジオボタンとして枠の丸と塗りつぶしの丸を描画

} else {
    // frame is circle
    framePath.addArc(withCenter: CGPoint(x:self.frame.height/2, y:self.frame.height/2),
                     radius: self.frame.height - margin*2 - 6,
                     startAngle: 0,
                     endAngle: CGFloat.pi * 2,
                     clockwise: true)
    framePath.stroke()
    // selected mark is filled circle
    checkPath.addArc(withCenter: CGPoint(x:self.frame.height/2, y:self.frame.height/2),
                     radius: self.frame.height - margin*2 - 9,
                     startAngle: 0,
                     endAngle: CGFloat.pi * 2,
                     clockwise: true)
    checkPath.fill(with: CGBlendMode.clear, alpha: 0)
    checkShapeLayer.strokeColor = UIColor.clear.cgColor
    checkShapeLayer.fillColor = tintColor.cgColor
}

 
ボタンのon/offは、
チェックマークの矩形を isHidden で出し隠ししている。

func on(){
    setTitleColor(tintColor, for: .normal)
    frameShapeLayer.strokeColor = tintColor.cgColor
    checkShapeLayer.isHidden = false
    isSelected = true
}

func off(){
    setTitleColor(baseColor, for: .normal)
    frameShapeLayer.strokeColor = baseColor.cgColor
    checkShapeLayer.isHidden = true
    isSelected = false
}

 
描画した矩形をviewに貼るタイミングは init 時にしている。
draw() はバックグラウンドから戻ってきたときなど複数回呼ばれるので。

convenience init(isMulti m: Bool, color c:UIColor) {
    self.init()
    isMulti = m
    tintColor = c
    isSelected = false
    layer.addSublayer(frameShapeLayer)   // ここで貼り付け
    layer.addSublayer(checkShapeLayer)   // ここで貼り付け
}

コード全体

以下をこぴぺでおk

長いわー