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

SwiftUI列表Section头部按钮:悬停折叠图标时检测失效求助

解决SwiftUI List Section头部hover折叠图标时失效的问题

问题核心原因:SwiftUI默认的Section折叠图标不在你自定义的header视图范围内,你的onHover只监听了自己写的HStack区域,鼠标移到折叠图标上时就脱离了检测范围,导致isHovered变为false。

以下是两种可行的解决方案,实现类似Apple Plan应用的效果:

方案一:利用Background扩展hover检测范围

通过给header的HStack添加一个透明背景,让背景填充整个Section头部区域(包括折叠图标所在位置),将onHover绑定到这个背景上:

@State private var isHovered = false
@State private var isShowingItemSheet = false // 补充原代码中缺失的状态
@Query(sort: \SoundBoard.createdAt) var soundBoards: [SoundBoard]

var body: some View {
    List{
        Section {
            ForEach(soundBoards) { board in
                Text(board.name)
            }
        } header: {
            HStack {
                Text("Mes soundboards")
                    .font(.subheadline)
                    .bold()
                Spacer()
                if isHovered {
                    Button("Add", systemImage: "plus.circle", action: { isShowingItemSheet = true })
                        .labelStyle(.iconOnly)
                        .tint(.accentColor)
                        .buttonStyle(.plain)
                }
            }
            // 关键修改:用透明背景扩展hover检测范围
            .background(
                Color.clear
                    .onHover { hovering in
                        isHovered = hovering
                    }
            )
        }
    }
}

方案二:用ZStack包裹全屏透明视图监听hover

通过ZStack将一个全屏的透明视图和原header内容叠加,让hover监听覆盖整个Section头部区域:

@State private var isHovered = false
@State private var isShowingItemSheet = false // 补充原代码中缺失的状态
@Query(sort: \SoundBoard.createdAt) var soundBoards: [SoundBoard]

var body: some View {
    List{
        Section {
            ForEach(soundBoards) { board in
                Text(board.name)
            }
        } header: {
            ZStack(alignment: .leading) {
                // 全屏透明视图,用于监听整个头部区域的hover
                Color.clear
                    .onHover { hovering in
                        isHovered = hovering
                    }
                // 原有的header内容
                HStack {
                    Text("Mes soundboards")
                        .font(.subheadline)
                        .bold()
                    Spacer()
                    if isHovered {
                        Button("Add", systemImage: "plus.circle", action: { isShowingItemSheet = true })
                            .labelStyle(.iconOnly)
                            .tint(.accentColor)
                            .buttonStyle(.plain)
                    }
                }
            }
        }
    }
}

两种方案都能实现:鼠标悬停在Section头部的任意区域(包括折叠图标)时,isHovered保持为true,Add按钮持续显示,符合你想要的交互效果。

内容的提问来源于stack exchange,提问作者Aurélien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:15:10