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
相关产品推荐
相关产品推荐

