article

Wednesday, August 11, 2021

SwiftUI Search Bar with Animations

SwiftUI Search Bar with Animations
ContentView.swift
 
//
//  ContentView.swift
//  swiftuidev
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {

    @State private var searchText = ""
    @State private var isEditing = false
    
    let countryList = Locale.isoRegionCodes.compactMap { Locale.current.localizedString(forRegionCode: $0) }
    var body: some View {
            NavigationView {
                List {
                    Section.init(header: SearchBar(text: $searchText, isEditing: $isEditing),
                    content: {
                        ForEach(countryList.filter( { searchText.isEmpty ? true : $0.contains(searchText) } ), id: \.self) { country in
                            Text(country)
                        }
                    })
                }
            .navigationTitle("Demo")
            .navigationBarHidden(isEditing).animation(.linear(duration: 0.25))
        }
    }
}

struct SearchBar: View {
    @Binding var text: String
    @Binding var isEditing: Bool
    
    init(text: Binding<String>, isEditing: Binding<Bool>) {
        self._text = text
        self._isEditing = isEditing
    }

    var body: some View {
        HStack {
            TextField("Search Country...", text: $text)
                .padding(7.5)
                .padding(.horizontal, 20)
                .background(Color(.systemGray6))
                .cornerRadius(7.5)
                .overlay(
                    HStack {
                        Image(systemName: "magnifyingglass")
                            .foregroundColor(.gray)
                            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                            .padding(.leading, 7.5)
                        
                        if isEditing && text.count != 0 {
                            Button(action: {
                                self.text = ""
                            }) {
                                Image(systemName: "multiply.circle.fill")
                                    .foregroundColor(.gray)
                                    .padding(.trailing, 7.5)
                            }
                        }
                    }
                )
                .padding(.horizontal, 10)
                .onTapGesture {
                    withAnimation {
                        self.isEditing = true
                    }
                }
            
            if isEditing {
                Button(action: {
                    withAnimation {
                        self.isEditing = false
                        self.text = ""
                    }
                    // Dismiss the keyboard
                    UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                }) {
                    Text("Cancel")
                }
                .padding(.trailing, 10)
                .animation(.linear(duration: 0.25))
            }
        }
        
        .textCase(.none)
        .frame(height: 50)
        .padding(0)
        .background(
            GeometryReader { proxy in
                Color(UIColor.systemBackground)
                .frame(width: proxy.size.width * 1.3, height: 100).fixedSize()
                    .offset(CGSize(width: -20.0, height: -50.0))
        })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Related Post