クリアメモリ

プログラミングやモーショングラフィックス、便利なアプリケーションなど雑多に記録するブログ

【Swift】背景色にグラデーションがかかったビューを作る

f:id:clrmemory:20170422185557p:plain 

今回はCocoa Programmingで、CustomViewの背景色にグラデーションをかける方法を紹介します。

背景色にグラデーションをかけることで、単色の背景より綺麗なレイアウトにできると思いますので、参考にしてみてください。

 

 

はじめに

 

今回紹介する方法は「Cocoa」で動作を確認しており、使用言語は「Swift」です。また、Xcodeを使ってアプリ開発を行っているため、その他のツールでは作り方が変わってくるので注意してください。

 

ではまず、実際の動作を確認しましょう。

 

 

このようにボタンをクリックすると、設置したCustomViewの色をグラデーションがかかった背景色にしてみました。

今回のグラデーションアプリでは「ストーリーボード」でオブジェクトを設置したので、早速作成していきましょう。

 

ストーリーボードを作る

 

今回のストーリーボードに設置するオブジェクトは「CustomView」と「Button」「Label」だけです。

以下を参考にして、ストーリーボードにオブジェクトを設置してください。

 

 

実際にグラデーションの背景にするために必要になるのは「CustomView」だけで良いのですが、ボタンのアクションをコードで設定するため、設置しないと動作しなくなります。

また、LabelとButtonは、CustomViewと同じ階層のオブジェクトです。

 

 

CustomViewの子オブジェクトにしてしまうと、背景にグラデーションをかけた時にボタンが隠れてしまいます。

では、これでストーリーボードの作成が完了したので、続いて今回作成するコードの流れを確認してください。

 

コードの流れ

 

今回のコードは以下のような流れで作成していきます。

 

・CustomViewのサブクラスを設定

・Viewクラスを作成

・CustomViewをOutlet接続

・ButtonをAction接続

・ランダムにグラデーションの色を設定

・サブビューが存在したら削除する

・一列ずつ描画する

・CustomViewにビューを追加

・繰り返し

 

では、実際のコードを作成しましょう。

 

CutomViewのサブクラスを作成

 

まず、CustomViewの背景色を白にするために、サブクラスを作成します。

 

 

CustomViewという名前で作成し、NSView型にしました。

作成したクラスの中に以下のような記述をして、デフォルトの背景色を設定してください。

 

import Cocoa

class CustomView: NSView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    layer?.backgroundColor = NSColor.white.cgColor
    }
}

 

このクラスを「ストーリーボード」から「CustomView」に設定します。

 

 

Viewクラスを作成

 

続いて、CustomViewに追加するビューの色を設定する「View」クラスを作成します。

 

 

作成したViewクラスには以下のように記述しておきます。

 

import Cocoa

class View: NSView {

    var red = CGFloat(0.0)
    var green = CGFloat(0.0)
    var blue = CGFloat(0.0)

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    self.layer?.backgroundColor = NSColor.white.cgColor
    NSColor(red: red, green: green, blue: blue, alpha: 1).set()
    NSBezierPath(rect: dirtyRect).fill()
    }
}

 

色を設定してぬりつぶすというコードになっているのですが、このコードは後ほどViewControllerから使用するので、現段階では特に動作しません。

 

ViewControllerを作成

 

ではViewControllerを作成していきます。まず先に実際のコードを確認してください。

 

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var customView: NSView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.view.window?.backgroundColor = NSColor.white
    }
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
    @IBAction func viewGradation(_ sender: NSButton) {
        var view = View()
        let width = customView.bounds.width
        let height = customView.bounds.height
        let gradationValue: CGFloat = 100

        let randomColor = arc4random_uniform(3)

        if customView.subviews.count != 0 {
            customView.subviews.removeAll()
        }
        for count in stride(from: CGFloat(0), to: height, by: CGFloat(1)) {
            view = View(frame: NSRect(x: 0, y: count, width: width, height: count+1))

            let gradationColor = CGFloat(count / height + (gradationValue/height))

            switch randomColor {
            case 0: view.red = gradationColor
            case 1: view.green = gradationColor
            case 2: view.blue = gradationColor
            default: view.red = gradationColor
            }

            customView.addSubview(view)
        }
    }
}

 

では順番に解説していきます。

 

CustomViewとButtonを接続

 

ViewControllerでは「CustomView」をOutlet接続、「Button」をAction接続しました。

 

@IBOutlet weak var customView: NSView!
@IBAction func viewGradation(_ sender: NSButton) {...}

 

これでViewControllerからボタンがクリックされた時の処理を実装できるようになります。

 

ランダムに色を設定

 

今回は「0〜2」までのランダムな数値を設定し、

0 -> 赤

1 -> 緑

2 -> 青

でグラデーションをかけていきます。

 

let randomColor = arc4random_uniform(3)

 

arc4random_uniform()は引数に与えられた個数でランダムな値を作成します。

これをswitch文の中で条件分岐させました。

 

ビューを削除

 

CustomViewにすでにサブビューが存在したままサブビューを追加してしまうと、アプリケーションの動作が重くなってしまいます。

そこで、すでにサブビューが存在している場合は、全消去する処理を追加しました。

 

if customView.subviews.count != 0 {
    customView.subviews.removeAll()
}

 

1列ずつ描画

 

今回のグラデーションでは、CustomViewの中に1列ずつサブビューを追加し、1列ごとに色を変えることでグラデーションにしています。

以下のように「for-in-stride」を使って、AからBまでC飛ばしで繰り返すという処理を作成しました。

 

for count in stride(from: CGFloat(0), to: height, by: CGFloat(1)) {...}

 

for文の中では、先ほど作成した「View」クラスにRectの範囲を設定しています。

今回は「count」で繰り返しの数を取得し、それに合わせてサブビューのy座標を設定しました。

 

繰り返しを途中で止めるとこのようになります。

左下が(0,0)の座標だということがわかりますね。

 

また、rectのheightを「count + 1」にすることで、「count座標から高さ1の図形」を作成できます。x座標、横幅はcustomViewの幅に合わせるので、0〜customView.bounds.widthですね。

 

サブビューを追加

 

最後にaddSubview(view)で、customViewのサブビューに作成したビューを追加しましょう。ここまでを繰り返すことで、順番にビューが追加されるということです。

 

徐々に色が変わっているため、グラデーションがかかっているように見えるかと思います。

 

ボタンをクリックするごとに、背景色が変わるのを確認してください。また、ボタンをたくさんクリックしても、アプリが重くならないことを確認しましょう。

 

まとめ

 

今回紹介した方法を使うことで、CustomViewの背景色にグラデーションをかけることができました。同様の方法で、設定する色を変更すれば「赤 -> 青」のようなグラデーションも設定できるかと思います。

 

ぜひ試してみてください。

ではまた。

新着記事