You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中带padding的Overlay按钮点击无响应问题求助

问题描述

我在Sheet展示的EVChargerView中添加了右上角关闭按钮,代码如下:

.overlay(
    Button {
        presentationMode.wrappedValue.dismiss()
    } label: {
        Image(systemName: "xmark")
    }
    .foregroundColor(.primaryAppColor)
    .font(.system(.title3, design: .rounded).weight(.light))
    .padding(.top, 20)
    .padding(.trailing, 20)
    , alignment: .topTrailing
)

但点击按钮毫无反应,奇怪的是移除按钮的padding修饰符后,按钮就能正常工作;另外,移除视图中的TabView组件后,按钮也能正常响应。完整视图代码如下:

import SwiftUI

struct EVChargerView: View {

//MARK: - PROPERTIES
@Environment(\.presentationMode) var presentationMode

@State private var selectedTab: Int = 0

@State private var showPhotosView: Bool = false

public let evCharger: EVChargerModel

private let tabs: [String] = [
    "Connectors",
    "Community",
    "Usage",
    "Address",
    "Operator"
]

//MARK: - BODY
var body: some View {
    
    ZStack {
        
        // Sets the background color
        Color.backgroundColor
            .ignoresSafeArea()
        
        VStack(alignment: .center, spacing: 10) {
            
            EVChargerPhotosView(mediaItems: evCharger.mediaItems)
                .frame(height: 250)
                .onTapGesture {
                    showPhotosView.toggle()
                }
                .sheet(isPresented: $showPhotosView) {
                    EVChargerPhotosView(mediaItems: evCharger.mediaItems, fillImages: false)
                }
            
            EVChargerTabView(
                tabTitles: tabs,
                selectedTab: $selectedTab
            )
            .padding(.horizontal, 15)
            
            TabView(selection: $selectedTab) {
                
                // Connectors tab
                EVChargerAllConnectionsView(connections: evCharger.connections)
                    .padding(.horizontal, 15)
                    .tag(0)

                // Community tab
                EVChargerAllCommentsView(userComments: evCharger.userComments)
                    .padding(.horizontal, 15)
                    .tag(1)

                // Usage tab
                EVChargerUsageView(usageType: evCharger.usageType, operatorInfo: evCharger.operatorInfo)
                    .padding(.horizontal, 15)
                    .tag(2)

                // Address tab
                EVChargerAddressView(addressInfo: evCharger.addressInfo)
                    .padding(.horizontal, 15)
                    .tag(3)

                // Operator tab
                EVChargerOperatorView(operatorInfo: evCharger.operatorInfo)
                    .padding(.horizontal, 15)
                    .tag(4)
                
            } //: TAB VIEW
            .tabViewStyle(.page(indexDisplayMode: .never))
            
        } //: VSTACK
        
    } //: ZSTACK
    .onAppear {
        selectedTab = 0
    }
    //TODO: - FIX X BUTTON ON THE TOP RIGHT SCREEN TO DISMISS THE VIEW. WHENEVER I REMOVE THE PADDING IN THE BUTTON, THE BUTTON WORKS.
    .overlay(
        Button {
            presentationMode.wrappedValue.dismiss()
        } label: {
            Image(systemName: "xmark")
        }
        .foregroundColor(.primaryAppColor)
        .font(.system(.title3, design: .rounded).weight(.light))
        .padding(.top, 20)
        .padding(.trailing, 20)
        , alignment: .topTrailing
    )
    
} //: BODY

} //: STRUCT

请问这是什么原因导致的?

问题原因
  • 点击区域被手势拦截:你给Button添加的padding是作用在Button本身,这会扩大Button的可点击区域。由于TabView使用了.page风格,它内置了左右滑动的手势识别器,优先级比Button的点击手势更高。当Button的扩展点击区域和TabView重叠时,TabView的手势会优先拦截点击事件,导致Button无法响应。
  • 无padding时的正常逻辑:移除padding后,Button的可点击区域仅局限于xmark图标本身,这个小区域没有和下方的TabView重叠,所以点击能正常触发;移除TabView后,没有手势拦截,自然也能正常响应。
解决方法

把padding移到Button的label内部,这样padding只会调整图标的位置,不会扩大Button的可点击区域,既保证图标位置正确,又避免点击区域被TabView拦截:

.overlay(
    Button {
        presentationMode.wrappedValue.dismiss()
    } label: {
        Image(systemName: "xmark")
            .foregroundColor(.primaryAppColor)
            .font(.system(.title3, design: .rounded).weight(.light))
            .padding(.top, 20)
            .padding(.trailing, 20)
    }
    , alignment: .topTrailing
)

内容的提问来源于stack exchange,提问作者Iraklis Eleftheriadis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:05:06