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

SwiftUI中如何设置Toolbar内SearchView的最大宽度?

问题:SwiftUI Toolbar内搜索栏无法设置最大宽度

我是SwiftUI新手,尝试给Toolbar里的搜索栏设置最大宽度,但使用.frame(maxWidth: .infinity)并未生效。

ToolbarView 代码

NavigationView {
    VStack {
        contentView
    }
    .padding(.top, 10)
    .navigationBarTitleDisplayMode(.inline)
    .toolbar {
        ToolbarItem(placement: .navigationBarLeading) {
            if (hideTitleAndSearchButton) {
                SearchBarView(
                    searchText: $viewModel.personViewModel.searchText,
                    hideTitleAndSearchButton: Binding(projectedValue: $hideTitleAndSearchButton),
                    viewModel: viewModel.personViewModel
                )
                .frame(maxWidth: .infinity)
                .animationDisable()
            }
            else {
                Text(title)
                    .font(.system(size: 32))
                    .bold()
            }
        }
        ToolbarItem(placement: .navigationBarTrailing) {
            if (!hideTitleAndSearchButton) {
                if (viewModel.setSearchButtonVisibility) {
                    Image(systemName: "magnifyingglass")
                        .onTapGesture {
                            self.hideTitleAndSearchButton = true
                        }
                        .frame(width: 45, height: 45)
                        .foregroundColor(Color.white)
                        .background(Color.mPurple)
                        .clipShape(Circle())
                        .animationDisable()
                }
            }
        }
    }
}
.frame(maxWidth: .infinity)

SearchBarView 代码

var body: some View {
    HStack {
        Image("back_icon")
            .resizable()
            .renderingMode(.template)
            .foregroundColor(.mPurple)
            .onTapGesture {
                self.isEditing = false
                self.searchText = ""
                self.hideTitleAndSearchButton = false
                viewModel.isSearchMode = false
                viewModel.isLoading = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                    viewModel.personPopularList.removeAll()
                    viewModel.getPersonPopular()
                }
            }
            .frame(width: 40, height: 40)
            .animationDisable()
        
            TextField("Search ...", text: $searchText)
            .padding(7)
            .padding(.horizontal, 20)
            .background(Color(.systemGray6))
            .cornerRadius(8)
            .accentColor(.mPurple)
            .frame(maxWidth: .infinity)
            .onTapGesture {
                self.isEditing = true
                viewModel.isSearchMode = true
            }.onChange(of: searchText) { searchItem in
                if (!searchItem.isEmpty) {
                    viewModel.searchText = searchItem.lowercased()
                    let _ = print("searchItem true")
                } else {
                    viewModel.isSearchMode = false
                    viewModel.personPopularList.removeAll()
                    viewModel.getPersonPopular()
                    let _ = print("searchItem false")
                }
                let _ = print("searchItemX: \(searchText)")
            }
            .animationDisable()
            .padding(.trailing, 10)
        }
}

解决方法

ToolbarItem的.navigationBarLeading和.navigationBarTrailing位置有固定宽度限制,直接设置maxWidth: .infinity无法突破这个约束,可通过以下方式解决:

  1. 更换ToolbarItem的位置:将搜索栏所在的ToolbarItem的placement从.navigationBarLeading改为.principal,该位置允许视图填充导航栏的全部可用宽度。
    修改后的ToolbarItem代码:
ToolbarItem(placement: .principal) {
    if hideTitleAndSearchButton {
        SearchBarView(
            searchText: $viewModel.personViewModel.searchText,
            hideTitleAndSearchButton: $hideTitleAndSearchButton,
            viewModel: viewModel.personViewModel
        )
        .frame(maxWidth: .infinity)
        .animationDisable()
    } else {
        Text(title)
            .font(.system(size: 32))
            .bold()
    }
}
  1. 优化搜索栏内部布局:在SearchBarView的HStack外层添加.frame(maxWidth: .infinity, alignment: .leading),确保内部元素正确排列且撑满宽度:
var body: some View {
    HStack {
        // 原有代码保持不变
    }
    .frame(maxWidth: .infinity, alignment: .leading)
}

原理:.principal是导航栏的主内容位置,容器会自动填充导航栏的剩余空间,此时设置maxWidth: .infinity就能让搜索栏撑满宽度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:35:35