6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUIのButtonは書き方によってタップ時に反応が異なるよ、という話

Posted at

よくButton("hogehoge", action: hoge)みたいな書き方を見るけれどButton(action:label:) とどう違うの?とかButtonStyleとどう違うの?とか どうでも良いことについて の解説。

検証環境

Xcode: Version 14.2 (14C18)
iOS target: 16.2

検証コード

import SwiftUI

struct ContentView: View {
    @State var isShowAlert = false
    var body: some View {
        ZStack {
            Color.brown
            VStack(spacing: 10) {
                Button("title", action: showAlert)
                    .foregroundColor(.white)
                    .padding(.horizontal, 50.0)
                    .padding(.vertical, 10.0)
                    .background(
                        RoundedRectangle(cornerRadius: 20)
                            .fill(.red)
                    )
                
                Button(action: showAlert){
                    Text("title")
                        .foregroundColor(.white)
                        .padding(.horizontal, 50.0)
                        .padding(.vertical, 10.0)
                        .background(
                            RoundedRectangle(cornerRadius: 20)
                                .fill(.red)
                        )
                }
                
                Button("title", action: showAlert)
                    .buttonStyle(.customStyle(color: .red))
            }
            .alert("メッセージ", isPresented: $isShowAlert) {
                Button("Continue", role: .cancel) { }
            }
        }
    }
    private func showAlert() {
        isShowAlert = true
    }
}

struct CustomButtonStyle: ButtonStyle {
    
    var color: Color = .blue
    
    public func makeBody(configuration: CustomButtonStyle.Configuration) -> some View {
        CustomButton(configuration: configuration, color: color)
    }
    
    struct CustomButton: View {
        let configuration: CustomButtonStyle.Configuration
        let color: Color
        
        var body: some View {
            
            return configuration.label
                .foregroundColor(.white)
                .padding(.horizontal, 50.0)
                .padding(.vertical, 10.0)
                .background(
                    RoundedRectangle(cornerRadius: 20)
                        .fill(color)
                )
                .opacity(configuration.isPressed ? 0.3 : 1.0)
        }
    }
    
}

extension ButtonStyle where Self == CustomButtonStyle {
    static func customStyle(color: Color = .red) -> some ButtonStyle {
        CustomButtonStyle(color: color)
    }
}

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

検証結果

button.gif

Buttonにモディファイアを付ける場合

paddingに反応しない。文字の領域をタップした時だけボタンが反応し、背景色が変わることはない。

init(action: label:)のlabelに装飾を付けた場合

今回はTextにモディファイアをつけた。
paddingに反応する。タップ時に背景色が薄くなるボタンらしい変化をする。

ButtonStyleで装飾を付けた場合

paddingに反応する。自分でタップした時の処理を指定しない場合は、色が薄くならない
今回opacityを0.3に設定したが、本来のボタンはもう少し薄い…。

まとめ

Buttonにモディファイアを付けることは反応の面からも止めたほうが良いと思う。
手軽に作るならばinit(action:label:)がベストだけれども、きちんと作るならばButtonStyleを使ったほうが良さそう。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?