SwiftUI:当列表太长时,SearchBar 移出边界

Posted

技术标签:

【中文标题】SwiftUI:当列表太长时,SearchBar 移出边界【英文标题】:SwiftUI: SearchBar moving out of bound when the List is too long 【发布时间】:2020-08-30 14:20:07 【问题描述】:

我在我的应用中的自定义标题内实现了一个搜索栏。在搜索栏下方,我添加了一个虚假的List,其中包含 100 行,旨在显示搜索结果。

我面临的问题是:

出现列表时,搜索栏会超出范围。当我添加 400 像素的顶部填充时,搜索栏会回到边界。 Link to video 1

接下来的两个有点跑题了。

当键盘在屏幕上时,列表的最后几行不可见。如何解决? Link to video 2 如何为List 设置背景颜色?我一直无法弄清楚。 (listRowBackground 修饰符没有按照我阅读的一篇文章的建议工作。)

我正在使用 Xcode 12.0 beta 6。

let screen = UIScreen.main.bounds

struct SearchBarView: View 
    @Binding var search: String
    @Binding var searchSelected: Bool
    
    var body: some View 
        VStack 
            CustomTextField(text: $search, isFirstResponder: true)
                .modifier(SearchBarTextFieldStyle(search: $search))

            if !search.isEmpty 
                  List(1..<100)  i in
                      Text("Hello \(i)")
                  .frame(width: screen.width)
            
        
        .frame(width: screen.width, height: !search.isEmpty ? screen.height : 40)
        .background(Color("ThemeColor"))
    

【问题讨论】:

【参考方案1】:

当列表出现时,搜索栏会移出边界。当我添加 400px 的顶部填充,搜索栏回到边界。

问题是所有东西都放在一个VStack 中。因此,当搜索不再为空时,TextFieldList 共享提供给它的空间。

TextField 放在一个单独的堆栈中,如下所示:

struct ContentView: View 
    
    @State var search: String = ""
    
    var body: some View 
        // Everything wrapped in one Stack
        VStack() 
            
            // Separate Stack for the TextField 
            HStack() 
                TextField("Title", text: self.$search)
            .padding()
            
            // One Stack for the content
            VStack 
                if !search.isEmpty 
                      List(1..<100)  i in
                          Text("Hello \(i)")
                      .frame(width: UIScreen.main.bounds.width)
                
            .frame(width: UIScreen.main.bounds.width)
                .background(Color.red)
            
            Spacer() // So that the TextField is also on top when no content is displayed 
        
    

当键盘在屏幕上时,列表的最后几行不是 可见的。如何解决?

在列表底部添加一个填充,但我建议实施此解决方案:Move TextField up when the keyboard has appeared in SwiftUI

例如带填充:

import SwiftUI

struct ContentView: View 
    
    @State var search: String = ""
    
    var body: some View 
        VStack() 
            
            HStack() 
                TextField("Title", text: self.$search)
            .padding()
            
            VStack 
                if !search.isEmpty 
                    List(1..<100)  i in
                        Text("Hello \(i)")
                    .frame(width: UIScreen.main.bounds.width)
                        .padding(.bottom, 300) // here padding
                
            .frame(width: UIScreen.main.bounds.width)
                
            
            Spacer()
        
    

如何为列表设置背景颜色?我没能 弄清楚。 (listRowBackground 修饰符不能作为 我读过的一篇文章建议的。)

这里也已经回答了这个问题: SwiftUI List color background

【讨论】:

感谢您的回复。将TextFieldList 分开并不能解决问题,因为两者都具有与以前相同的父容器。但是,我做了一个解决方法并用键盘高度降低了父母的高度(如你所建议的)并添加了一个Spacer。这解决了 2 个问题,将搜索栏带入边界并从 List 中取消隐藏行。您为List 背景颜色指向我的链接对我来说不起作用。可能是因为我解释不好,解决方案中没有给出解释。 正如您在我的第一个示例中看到的那样,TextFieldList 也共享一个 parent 。当没有List 时,Spacer 需要将TextField 保持在顶部。我刚刚在代码的 cmets 中写了它,但没有提到它。我提供的代码在 ios 13.5.1 下为我工作。但很高兴你能解决它 嘿!抱歉回复晚了:'(不幸的是,我没有在我的设备上使用 iOS 13,所以我无法对此发表评论。在 iOS 14 中它似乎不起作用。无论如何感谢您的回答。感谢它。

以上是关于SwiftUI:当列表太长时,SearchBar 移出边界的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 2个问题但很简单,关于searchBar和list的backgroundImage

如何在 SwiftUI 中滚动时隐藏 SearchBar?

SwiftUI:自定义SearchBar

如何在 SwiftUI 列表中重新加载数据?

SwiftUI 如何将数据传递给 ObservedObject 函数

占用太多空间的 Swiftui 小部件列表