SwiftUI Modiferを用意してNeumorphismにしてしまえ

By: yoppe
Posted: 2020-04-27

 

 

概要

SwiftUIのColortとViewを拡張して、Modifierをつければスタイルを適用できるようにする方法を書いていく。いちいち色を指定してドロップシャドウをして、というのは効率的でないので、Modifierにしてしまえという発想。

ちなみにNeumorphismはデザイン手法の一つ。New(新しい)+Skeumorphism(スキューモーフィズム)から来ているらしい。基本的に、2つのドロップシャドウを使用することで、単色ながら立体感をだし、ちょっとモダンなビジュアルになるのが特徴。

 

まずはColorを拡張する

import SwiftUI
extension Color {
    static let neuBackground = Color(hex: "f0f0f3")
    static let dropShadow = Color(hex: "aeaec0").opacity(0.4)
    static let dropLight = Color(hex: "ffffff")
}

extension Color {
    init(hex: String) {
        let scanner = Scanner(string: hex)
        scanner.scanLocation = 0
        var rgbValue: UInt64 = 0
        scanner.scanHexInt64(&rgbValue)

        let r = (rgbValue & 0xff0000) >> 16
        let g = (rgbValue & 0xff00) >> 8
        let b = rgbValue & 0xff

        self.init(red: Double(r) / 0xff, green: Double(g) / 0xff, blue: Double(b) / 0xff)
    }
}
 

見た目を確認する

Image(systemName: "forward.fill")
.padding(padding)
.background(
  RoundedRectangle(cornerRadius: 10)
  .fill(Color.neuBackground)
)
.shadow(color: .dropShadow, radius: 15, x: 10, y: 10)
.shadow(color: .dropLight, radius: 15, x: -10, y: -10)
.foregroundColor(.primary)
 

Viewを拡張してModifierを作る

extension View {
    func neumorphism(padding: CGFloat)->some View {
        self.modifier(NeumorphismModifier(padding: padding))
    }
}

struct NeumorphismModifier: ViewModifier {
    var padding: CGFloat = 5
    func body(content:Content) -> some View {
        ZStack(content: {
            content
                .padding(padding)
                .background(
                    RoundedRectangle(cornerRadius: 10)
                    .fill(Color.neuBackground)
                )
                .shadow(color: .dropShadow, radius: 15, x: 10, y: 10)
                .shadow(color: .dropLight, radius: 15, x: -10, y: -10)
                .foregroundColor(.primary)
        })
    }
}
 

あとはこれでいい

拡張子を作ったので、Viewにつけるだけ

Image(systemName: "forward.fill")
.neumorphism(padding: 10)
 

まとめ

今回はNeumorphismにするためのModifierを作った。こうやって切り出して一つの処理にまとめると気分がいいですね。a

 

参考になるリンクなど

チュートリアルから一歩踏み出したSwiftUIのCustom Viewの作り方ーその3(ViewModifier編) - Qiita
付箋のView生成部分のコードがわかりずらかったので全面的に書き直しました。(7/Nov/2019) 前回のPreferenceKeyの 記事が重かったので、今回は軽めの内容です。 SwiftUIには色々な Modifierが準備されています。下記の例ですと font, lineLimit, frame, foregroundColor がそれにあたります。簡単にUIの変更が出来てとても便利ですね。 SwiftUIではさらに ViewModifierを利用してカスタムのModifierを作ることが出来ます。 今回は下記のように Textを付箋のように表示する Modifier を作ってみたいと思います。 ViewModifier プロトコルを継承してカスタマイズViewModifierを作ります。そのためには func body(content: Self.Content) -> Self.Bodyを実装しなければなりません。 contentはモディファイする対象のViewへのProxyになります。前述の例でいうと Text("If today were the last day of my life, would I want to do what I am about to do today")になります。下の例では対象のViewのbackgroundとして StickyNoteという名のViewが表示されますので、今回の付箋の例では StickyNoteのViewで付箋の画像を生成すれば良いという訳です。非常にわかりやすく、簡単です。 ひとつ注意点としては backgroundを設定する前に paddingを使って付箋のサイズを前もって設定しなければならない点です。なぜなら StickyNote側の GeometryReaderで content のサイズ(付箋の矩形のサイズ)を取得する必要があるからです。 次に付箋の画像生成部分です。 GeometryReaderを使って対象Viewのサイズを取得し Pathを使って画像を生成して返しています。GeometryReaderに関しては過去記事( チュートリアルから一歩踏み出したSwiftUIのCustom Viewの作り方ーその1(GeometryReader編))を参考にしてください。 最後に ModifierをViewのメソッドにして可読性を高めます。 これにより.modifier(StickyNoteModifier()ではなく.StickyNote() で使えるようになります。 Modifierを使うと、非プログラマーが関与する必要がない部分を隠蔽し、デザイナーなど非プログラマーがLiveViewを見ながらUIを細かに調整することを、簡単なパラメーターの変更のみで可能にします。 今回の例ですと、色、コーナーの大きさ、付箋の折り返し部分の大きさなどを調整することができます。もちろん文字長が変わっても、複数行になっても自動で調整されます。 color ceaseSize cornerRadius shadowLength Creative Technologist。世界最大、最高のハードウェアアクセラレータ"HAX"の数少ない日本人の卒業生。 ハード、ソフトがいい具合に絡んだ製品、サービスのアイディエーション、コンセプトワーク、ラピッドプロトタイピング、アジャイル開発、マーケティングなどを生業にしています。 お仕事募集中。ただしVancouver(Canada)からのリモートワークです。 Why not register and get more from Qiita?
チュートリアルから一歩踏み出したSwiftUIのCustom Viewの作り方ーその3(ViewModifier編) - Qiita