SwiftUI

SwiftUIでグラデーションButtonを描画してみた

環境

  • macOS Catalina (10.15.6 beta)
  • Xcode 11.6

SwiftUIでグラデーションを描写

UIKitではいくらでもグラデーションを描写できるのですが、SwiftUIでの情報が少なかったので実装してみました。結論からいうとLinearGradientという名前のものがあるのでこれでグラデーションを描写できます。

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen public struct LinearGradient : ShapeStyle, View {

    public init(gradient: Gradient, startPoint: UnitPoint, endPoint: UnitPoint)

    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required `body` property.
    public typealias Body
}

初期値に3つの引数gradient, startPoint, endPoint が存在する

gradient 後に紹介するグラデーションGradientを代入します
startPoint 始点
endPoint 終点

Gradientは2つの初期化メソッドがあります。

/// Initialize with an array of color stops.
    public init(stops: [Gradient.Stop])

    /// Initialize with an array of colors, location values will be
    /// synthesized to evenly space the colors along the gradient.
    public init(colors: [Color])

よく使いそうなのが2つめの複数のカラーをセットできる初期化メソッドではないかと思われます。

LinearGradientの宣言の仕方は

let gradientView = LinearGradient(
        gradient: Gradient(colors: [Color.red, Color.green]),
        startPoint: .leading,
        endPoint: .trailing)

という感じでグラーデションに使う複数カラーを指定して、始点と終点を代入する感じになるかと思います。

ここで宣言したgradientView をViewの背景色プロパティ.backgroundに入れるやり方です。

試しにUILabelでいうところのViewをグラデーション描写させてみます。

let gradientView: LinearGradient = LinearGradient(gradient: Gradient(colors: [Color.red, Color.green]), startPoint: .leading, endPoint: .trailing)

Text("ラベル")
                .frame(minWidth: 0, maxWidth: .infinity)
                .padding()
                .foregroundColor(.white)
                .background(gradientView)
                .cornerRadius(40)

これをビルドすると次のような画面が表示されます。

ViewとButtonとText それぞれにグラデーションを描写する

上記はTextでしたが、次はUIKitでいうところのUIView、UIButton、UILabelにSwiftUIでグラデーションを描写する方法を見ていきます。UIView, UIButton, UILabel はSwiftUIでは下の図のようなコンポーネントで置き換えられます。

UIKit SwiftUI
UIView Divider
UIButton Button
UILabel Text

これからDivider, Text, Button それぞれにグラデーションを描写していきます。

import SwiftUI

struct ContentView: View {
    
    let gradientView = LinearGradient(
        gradient: Gradient(colors: [Color.red, Color.green]),
        startPoint: .leading,
        endPoint: .trailing)
    
    var body: some View {
        
        VStack(spacing: 10) {
            /// テキスト
            Text("ラベル")
                .frame(minWidth: 0, maxWidth: .infinity)
                .padding()
                .foregroundColor(.white)
                .background(gradientView)
                .cornerRadius(40)
            
            /// ボタン
            Button(action: {
                print("Tap Action")
            }, label: {
                Text("グラデーションボタン")
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .padding()
                    .foregroundColor(.white)
                    .background(
                        gradientView)
                    .cornerRadius(40)
            })

            /// View
            Divider()
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 20)
                .padding()
                .foregroundColor(.white)
                .background(gradientView)
                .cornerRadius(40)
        }
    }
}

これで出来上がりです。それぞれのコンポーネントのbackgroundプロパティにgradientViewを代入しました。

これをビルドすると次の画面が表示されます。

SwiftUIでグラデーションを描写するのは意外と簡単でしたね。

それでは、バイバイ。

ABOUT ME
tamappe
都内で働くiOSアプリエンジニアのTamappeです。 当ブログではモバイルアプリの開発手法について紹介しています。メインはiOS、サブでFlutter, Android も対応できます。 執筆・講演のご相談は tamapppe@gmail.com までお問い合わせください。