简体   繁体   中英

Changing size of tappable Button area – contentShape(_:) not working

I'm making a custom tab bar in SwiftUI using TabView(selection:) and hiding the default tab in ContentView 's init (not a good practice, I know).

I have two tab buttons in the tab view, like this:

HStack(spacing: 0) {
    Button(action: { selectedTab = .history  }) {
        EmptyView()
    }
    .buttonStyle(TabButtonStyle(systemImage: "rectangle.stack.person.crop", tab: .history, currentTab: selectedTab))
    
    Spacer()
    
    Button(action: { selectedTab = .profile }) {
        EmptyView()
    }
    .buttonStyle(TabButtonStyle(systemImage: "person.crop.circle", tab: .profile, currentTab: selectedTab))
}
.overlay(tapButton)
.padding(.horizontal, 50)
.padding(.vertical, 10)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.ignoresSafeArea(.all, edges: .bottom)

tapButton is a custom tab button overlayed on top, and the paddings are to recreate the dimensions of the default tab bar.

With TabButtonStyle (necessary for the custom behaviour where the image switches to its filled alternative when the user is pressing it, not after they release their finger) like this:

struct TabButtonStyle: ButtonStyle {
    let systemImage: String
    let tab: Tab
    var currentTab: Tab
    
    func makeBody(configuration: Configuration) -> some View {
        return Image(systemName: configuration.isPressed || tab == currentTab ? "\(systemImage).fill" : systemImage)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 25, height: 25)
    }
}

Although this works like a charm, the tappable area ends up just being the image, which is too small and finicky for our fingers. The usual way to change this is to add the contentShape(_:) modifier – however, when I add it (either to the TabButtonStyle or after the Buttons themselves), the button isn't tappable anymore. It doesn't respond to taps, regardless of the Shape that I give in the argument.

Is there something I'm doing wrong here, maybe because of the EmptyView ? Even if without the contentShape(_:) it works perfectly fine? Maybe this is due to the inner workings of contentShape(_:) .

Adding padding works with Xcode 12.1 / iOS 14.1

return Image(systemName: configuration.isPressed || tab == currentTab ? "\(systemImage).fill" : systemImage)
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 25, height: 25)
    .padding()                      // << here !!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM