user25917
user25917

Reputation: 987

Expand SwiftUI button tap area over the button frame

I read a similar question about that issue. But that only expand the button size use .padding(). The red region in the snapshot is the tappable area.

The trailing padding to screen edge inserted by SwiftUI.framework can not be removing (I think). That causes any tap in the right edge of the screen can not trigger button action. How can I make the tappable area beyond the button size? So that user could tap that button more easier.

Thanks.

enter image description here

.navigationBarItems(trailing:
    Button(action: {
        self.context.isSheetDisplay = true
    }, label: {
        Image(systemName: "square.and.pencil")
            .font(.system(size: 20))
    })
    .padding([.leading, .top, .bottom])
    .background(Color.red)
)

Update:

e.g. The Photos.app in simulator could trigger tap at the edge. enter image description here

Upvotes: 10

Views: 5051

Answers (3)

TannenzapfenStock
TannenzapfenStock

Reputation: 51

So basically you need to give the label of the Button a padding and then give the button an offset with this padding. This is how I did it:

Button {
    print("Tapped")
} label: {
    Image(systemName: "xmark.circle.fill")
        .foregroundColor(.grayColor.opacity(0.7))
        .padding(EdgeInsets(top: 15, leading: 15, bottom: 15, trailing: 15))
}
.background(.red) // Shows the tappable area
.offset(x: 20, y: -20)

Upvotes: 0

Edward Brey
Edward Brey

Reputation: 41728

The hit test area includes the background, but only when it isn’t clear. If your button is overlaying an area with a uniform background, you can make its background not clear, while still not noticeable to the user, by setting its background to the background color.

Button(…)
    .background(.background)

Upvotes: 1

MarkFromMars
MarkFromMars

Reputation: 386

My solution to this issue for iOS is to add a nearly transparent background color ViewModifier to the button as part of a ButtonStyle:

import SwiftUI

struct ExampleBigPaddedButton: View {
    var body: some View {
        Button("Tap anywhere inside") {
            print("Tapped")
        }.buttonStyle(BigPaddedButtonStyle())
    }
}

struct BigPaddedButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        return configuration
            .label
            .foregroundColor(configuration.isPressed ? .gray : .black)
            .padding(EdgeInsets(top: 75, leading: 25, bottom: 75, trailing: 25))
            .background(Color(red: 1, green: 1, blue: 1, opacity: 0.01))
            .background(Rectangle().stroke(Color.gray))
    }
}

struct ExampleBigPaddedButton_Previews: PreviewProvider {
    static var previews: some View {
        ExampleBigPaddedButton()
    }
}

This produces a button having any size of padding you need that is tappable anywhere within its bounds.

Upvotes: 0

Related Questions