如何让macOS上SwiftUI搜索视图整体显示聚焦高亮(含搜索图标)
macOS SwiftUI Toolbar 搜索视图聚焦高亮范围问题
问题背景
为SignDict适配macOS与visionOS,iPadOS上表现正常,但macOS端存在聚焦高亮问题:
- 自定义搜索视图由HStack包裹SF Symbol图标与TextField,置于ToolbarItem中
- macOS上搜索视图获得焦点时,蓝色聚焦环仅覆盖TextField区域,而非整个包含图标的HStack
- 需求:仅在原生macOS下让整个搜索视图显示聚焦高亮,iPad适配模式不生效
原代码
ToolbarItem { HStack(spacing: 5) { Image(systemName: "magnifyingglass") .foregroundStyle(.gray) TextField("Search", text: $searchText) } .padding(.horizontal, 10) .frame(width: 220, height: 30) }
解决方案
1. 添加焦点状态变量
在视图结构体中新增以下状态变量,用于跟踪搜索框的焦点状态:
@State private var searchText = "" @FocusState private var isSearchFocused: Bool
2. 重构搜索视图代码
修改ToolbarItem中的搜索视图,让整个HStack成为可聚焦容器,并自定义匹配系统风格的聚焦样式:
ToolbarItem { HStack(spacing: 5) { Image(systemName: "magnifyingglass") .foregroundStyle(.gray) TextField("Search", text: $searchText) .textFieldStyle(.plain) // 隐藏TextField默认边框与聚焦环 .focused($isSearchFocused) } .padding(.horizontal, 10) .frame(width: 220, height: 30) .background(Color(.textBackgroundColor)) .cornerRadius(6) #if os(macOS) .focusable() .onTapGesture { isSearchFocused = true // 点击容器时将焦点传递给TextField } .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color.accentColor, lineWidth: 2) .opacity(isSearchFocused ? 1 : 0) ) // 排除iPad适配macOS的场景 .disabled(ProcessInfo.processInfo.isiOSAppOnMac) #endif }
关键细节说明
.textFieldStyle(.plain):移除TextField默认的边框和聚焦样式,避免与自定义聚焦环冲突。.focusable():让整个HStack成为可接收焦点的区域,支持键盘导航聚焦。onTapGesture:保证点击搜索容器的任意区域(包括图标)都能激活TextField的输入状态。- 自定义
overlay:绘制与系统风格一致的蓝色聚焦边框,仅在焦点激活时显示。 ProcessInfo.processInfo.isiOSAppOnMac:精准判断当前是否为iPad适配模式,确保自定义样式仅作用于原生macOS。
内容的提问来源于stack exchange,提问作者Antonio A. Chavez
相关产品推荐
相关产品推荐

