1

I've implemented a search bar in my app inside a custom header. Beneath the search bar I have added a false List with 100 rows that is intended to show search results.

The problem that I'm facing is:

  • when the list appears, the search bar moves out of bounds. When I add a top padding of 400px, the search bar comes back to bounds. Link to video 1

The next two are a bit out of topic.

  • When the keyboard is on screen, the last few rows of the list are not visible. How to fix it? Link to video 2
  • How to set a background color for a List? I haven't been able to figure that out. (listRowBackground modifier isn't working as suggested by an article I read.)

I'm using 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"))
    }
}
Praduyt Sen
  • 137
  • 1
  • 8

1 Answers1

2

when the list appears, the search bar moves out of bounds. When I add a top padding of 400px, the search bar comes back to bounds.

The issue is that everything is placed in one VStack. So when search is not empty anymore the TextField shares the space provided to it with the List.

Place the TextField in a separate Stack like this:

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 
        }
    }
}

When the keyboard is on screen, the last few rows of the list are not visible. How to fix it?

Add a padding to the bottom of the list but I'd recommend implementing the solution of this: Move TextField up when the keyboard has appeared in SwiftUI

E.g. with padding:

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()
        }
    }
}

How to set a background color for a List? I haven't been able to figure that out. (listRowBackground modifier isn't working as suggested by an article I read.)

This question has also already been answered here: SwiftUI List color background

Simon
  • 1,754
  • 14
  • 32
  • Thanks for your reply. Separating the `TextField` and `List` doesn't solve the issue as both have same parent container as before. However, I did a work around and decreased the parents height with the keyboard height(as suggested by you) and added a `Spacer`. This solved 2 problems, bringing the search bar to bounds and unhiding rows from the `List`. The link you directed me for the `List` background color didn't work out for me. Maybe because I couldn't interpret it well, as there is no explanation given in the solution. – Praduyt Sen Aug 31 '20 at 06:29
  • As you can see on my first example the ```TextField``` and ```List``` also share a parent . The ```Spacer``` is required to keep the ```TextField``` on top when no ```List``` is there. I had just written it in the comments of the code but not mentioned it. The code I provided is working for me under iOS 13.5.1. But glad you could solve it – Simon Aug 31 '20 at 10:05
  • Hey! sorry for the late reply :'( Unfortunately I'm not using iOS 13 on my device, so i can't comment on it. In iOS 14 it doesn't seem to work. Anyways thanks for your answer. Appreciate it. – Praduyt Sen Sep 02 '20 at 13:00