見出し画像

[SwiftUI]tinder風アプリ作ってみる: Button編

tinder風アプリ作ってみた: Button編


こんばんわ。なかがわ(Twitter)です。
休日いかがお過ごしでしょうか?
私はというと、父の日ということで少し早めですが
実家に父親の好物であるモンブランケーキを持っていきました。

さて、では前回の続きをやっていきましょう。
今日はButton(ボタン)について見ていきます。


参考動画はこちら : yusuke さん
非常に丁寧に解説してくださっており、理解が深まります。
ぜひこちらも見てみてください。


[アプリ内のButton設計]


では、アプリ内部で使われているボタンを見ていきます
大体の完成目標図はこちらでしたね↓

参照: Tinder公式より

前回は大まかに画面デザインを作成しました↓


ボタン使用設計:

画面上部に4つ(画面端に2つ、中央に2つ[だ円枠])
画面下部に5つ(大きさが交互に大小で並んでいる[丸枠])

ボタンは現時点で合計9個使われており、
形の種類も3種類ほどありますね。

・枠なしイラストのみのボタン
・丸枠ボタン
・楕円形の枠ボタン

一つ一つボタンコードをベタ書きすると非常にみづらく
冗長になってしまうので、別のstructを作成して
各ボタンのデザインをそれぞれ格納しておき、
必要な分だけContentViewに呼び出していきます。

ではまず、各ボタンデザインのコードを見ていきましょう。

・ButtonView(枠なしの通常ボタン)


まずは枠無しのボタンですね。
1. var iamgeName: String  2. var imageSize: Int
二つのプロパティを宣言し、ボタン呼び出し時に
引数として渡してあげます。
マークロゴにはSF Symbolを使っています。
:

SF Symbolsとは:

簡単に言うと「アプリ内で使用できるカスタマイズ(編集)可能なシンボル」です。iOS13以降に標準で用意されており、アプリ開発時にImageビューで自分で用意した画像の代わりに、SF Symbolsを使用することができます。

SF Symbolはこちらでダウンロードすることで開発内で使用可能です。
英語なので、Google翻訳等を利用してどうぞ
ダウンロードサイト

ではコードです↓

// ✅通常のボタンView
struct ButtonView: View {

    // SF Symbolのシンボル名を呼び出し時に渡す
    var imageName: String
    // frameモディファイア内の指定数値を呼び出し時に渡す
    var imageSize: CGFloat

    var body: some View {

        Button (action: {
        }) {
            // Image(systemName: "<シンボル名>") ← これでSFSymbolのアイコンが呼び出せます
            Image(systemName: imageName)
                .resizable()
                .scaledToFill()
                .frame(width: imageSize, height: imageSize, alignment: .center)
        }
    }
}

[ 呼び出し時のコード ]

// imageName: SE Symbolのシンボル名
// imageSize: シンボルのフレーム枠として渡す値
ButtonView(imageName: "person.fill", imageSize: 30)


・CircleButtonView(丸枠ボタン)


次に丸枠ボタンです。
上記ボタンの記述に加えて、ZStackで囲んで奥の面に丸枠を作り、
輪郭にshadow(影)をつけています。

// ✅丸枠のボタンView
struct CircleButtonView: View {

    var imageName: String
    var imageSize: CGFloat
    // 丸枠のframe数値を呼び出し時に渡す
    var backGroundSize: CGFloat

    var body: some View {

        ZStack {   // ZStackでボタンと丸枠を重ねる

            // 丸枠を作成
            Color.white.frame(width: backGroundSize, height: backGroundSize)
                .cornerRadius(50)
            // 影をつける
                .shadow(radius: 10)

            Button (action: {
            }) {
                // ボタンの外見部分
                // ボタンの見た目は、ImageでSF Symbolを使っています
                Image(systemName: imageName)
                    .resizable()
                    .scaledToFill()
                    .frame(width: imageSize, height: imageSize, alignment: .center)

            } // BottomButton
        } // ZStack
    }
}

[ 呼び出時のコード ]

// backGroundSize: 丸枠のframe数値を渡す
CircleButtonView(imageName: "gobackward", imageSize: 20, backGroundSize: 40)


・EllipseButtonView(楕円形枠ボタン)


3つ目は楕円形ボタンです。
上記二つのデザインと違って横長にしたいので、
frame内の縦横の値をそれぞれ別で渡せるように、
プロパティを二つ作ってます。

// ✅楕円枠のボタンView
struct EllipseButtonView: View {

    var imageName: String
    var imageSize: CGFloat
    // 横長にするため、frameの縦横の数値が異なる
    // widthとheightで別のプロパティを作って、frameにそれぞれ値を渡せるように
    var backGroundWidthSize: CGFloat
    var backGroundHeightSize: CGFloat

    var body: some View {

        ZStack {

            // 楕円形枠の作成
            // ZStackで囲み、重ねる
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .fill(Color.white)
                // 縦と横の値をそれぞれ別の値で指定できるように
                .frame(width: backGroundWidthSize, height: backGroundHeightSize)
                .shadow(radius: 10)

            Button (action: {
            }) {
                // ボタンの外見部分
                // ImageにSF Symbolを使っています
                Image(systemName: imageName)
                    .resizable()
                    .scaledToFill()
                    .frame(width: imageSize, height: imageSize, alignment: .center)

            } // BottomButton
        } // ZStack
    }
}

[ 呼び出し時のコード ]

// backGroundWidthSize: frameの横数値を渡す
// backGroundHeightSize: frameの縦数値を渡す
EllipseButtonView(imageName: "flame.fill", imageSize: 20, backGroundWidthSize: 50, backGroundHeightSize: 40)

[全体のコード]


では、上記を踏まえた上で全体のコードを見ていきます。
上記で作った各ボタンデザインをContentView構築の中で
必要文呼び出しています。

struct ContentView: View {

    // 画面の横幅をiPhoneのフレームラインに合わせる
    private var frameWidth: CGFloat {UIScreen.main.bounds.width}

    var body: some View {

        VStack {

            // 画面上部のボタン群
            HStack() {
                ButtonView(imageName: "person.fill", imageSize: 30)
                Spacer()
                EllipseButtonView(imageName: "flame.fill", imageSize: 20, backGroundWidthSize: 50, backGroundHeightSize: 40)
                EllipseButtonView(imageName: "leaf.fill", imageSize: 20, backGroundWidthSize: 50, backGroundHeightSize: 40)
                Spacer()
                ButtonView(imageName: "message.fill", imageSize: 30)
            }// HStack
            .padding()
            .frame(width: frameWidth, height: 50)

            // 写真が表示される部分
            Text("Image")
                .padding()
                .frame(width: frameWidth, height: 600)
                .background(Color.blue)


            // 画面下部のボタン群
            HStack(spacing: 20) {
                CircleButtonView(imageName: "gobackward", imageSize: 20, backGroundSize: 40)
                CircleButtonView(imageName: "xmark", imageSize: 20, backGroundSize: 50)
                CircleButtonView(imageName: "star.fill", imageSize: 20, backGroundSize: 40)
                CircleButtonView(imageName: "suit.heart.fill", imageSize: 20, backGroundSize: 50)
                CircleButtonView(imageName: "bolt.fill", imageSize: 15, backGroundSize: 40)
            }

        } // VStack
    } // body
} // View

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


[まとめ]


以上、アプリ内に実装されているボタンのデザインを実際に構築してみました。
さらに構築を進めて、キリのいいところでまた記事にまとめていきたいと思います。
ではでは。良い休日を✊

以上


いいなと思ったら応援しよう!