Giter Club home page Giter Club logo

swiftlysearch's Introduction

THIS PROJECT IS OBSOLETE

iOS 15 introduced .searchable(), which is an official search bar implementation for SwiftUI. As such this project is now obsolete. I will continue to keep it around as a polyfill for apps targeting <iOS 15, but it will no longer be actively developed and you should switch to the new system as soon as you can. Thank you all for your support, and happy coding!

SwiftlySearch

A small, lightweight UISearchController wrapper for SwiftUI

Installation

Manual:

Update your Package.swift file:

let package = Package(
  ...,

  dependencies: [
    .package(
      url: "https://github.com/thislooksfun/SwiftlySearch.git",
      from: "1.0.0"),

    ...
  ],

  ...
)

In Xcode:

  1. Go to File > Swift Packages > Add Package Depencency...
  2. Enter https://github.com/thislooksfun/SwiftlySearch as the URL
  3. Select your desired versioning constraint
  4. Click Next
  5. Click Finish

Usage

import SwiftlySearch

struct MRE: View {
  let items: [String]

  @State
  var searchText = ""

  var body: some View {
    NavigationView {
      List(items.filter { $0.localizedStandardContains(searchText) }) { item in
        Text(item)
      }.navigationBarSearch(self.$searchText)
    }
  }
}

Known issues:

(#12) NavigationLinks inside the resultContent don't work. This is a limitation of the UIKit/SwiftUI interaction, and thus out of my hands. If you require a seperate view for displaying search results you can use a workaround like shown below:

struct ContentView: View {
    @State
    var searchText: String = ""

    var body: some View {
        NavigationView {
            ZStack {
                if searchText.isEmpty {
                    NormalView()
                } else {
                    SearchResultsView(text: searchText)
                }
            }
            .navigationBarSearch($searchText)
        }
    }
}

struct NormalView: View {
    var body: some View {
        Text("Some view")
    }
}

struct SearchResultsView: View {
    var text: String

    var body: some View {
        VStack {
            Text("You searched for \(text)")
            NavigationLink(destination: Text(text)) {
                Text("Let's go!")
            }
        }
    }
}

swiftlysearch's People

Contributors

alexeichhorn avatar joelago avatar thislooksfun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftlysearch's Issues

Binding text not updated when it changes outside SearchBar

It seems that the binded search text variable is not updated when the value changes outside the SearchBar view. In other words, the search view is not updated with the new @State variable contents.

Not sure if this is has something to do with the multiple Bindings happening between the SearchBar structure and other coordinators classes, etc?

Updated properties are not propagated correctly into the search bar coordinator

Consider the following example:

struct MyView {
    @State var searchText: String = ""
    @State var placeholder: String = "abc"

    var body: some View {
        NavigationView {
            Button("Click me") { self.placeholder = "123" }
                .navigationBarTitle("Test \(placeholder)")
                .navigationBarSearch($searchText, placeholder)
        }
    }
}

One would expect that clicking the button correctly changes both the search placeholder and the title. It, however, only changes the title:

image

Thus the issue seems to be with the search bar. Digging a little deeper, I found that while the SearchBar initializer is invoked correctly after the state update, no new Coordinator is instantiated, thus leaving it with outdated values.

A possible solution might be to update the coordinator in

func updateUIViewController(_ controller: SearchBarWrapperController, context: Context) {
controller.searchController = context.coordinator.searchController
controller.hidesSearchBarWhenScrolling = hidesSearchBarWhenScrolling
controller.text = text
if let resultView = resultContent(text) {
(controller.searchController?.searchResultsController as? UIHostingController<ResultContent>)?.rootView = resultView
}
}

I am not sure how idiomatic of a solution that would be though.

hidden by default? avoid popping in

Is there a way to have the search bar hidden by default? Currently it just pops in for me and just looks a little jarring. I'm on Xcode 12 beta 3

List(mylist.filter { searchText == "" ? true : $0.name.localizedStandardContains(searchText) }, id: \.id){ item in
            HStack{
                    Text(item.name)
            }
        }
        .navigationBarTitle("Artists")
        .navigationBarSearch(self.$searchText, placeholder: "Find in Artists")

UI content jumps up and down during transition

I love how smooth this works when using the list as per your example code, however I am trying to use this with different elements. I have setup an example of where the jumping can occur (ScrollView + VStack).

import SwiftUI
import SwiftlySearch

struct MoviesView: View {
    
    let items: [String] = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ"]
	
    @State
    private var searchText = ""
    
    var body: some View {
        ScrollView {
            VStack {
                ForEach(items.filter { searchText == "" || $0.localizedStandardContains(searchText) }, id: \.self) { item in
                    Text(item)
                }
            }
        }
        .navigationBarTitle("Movies")
        .navigationBarSearch(self.$searchText)
    }

}

Here is a recording of the issue which I hope helps to explain
Sep-18-2020 20-42-54

I am just learning SwiftUI and have no experience with UIKit otherwise I would spend more time trying to fix this myself.
Let me know if you have some ideas and I can do some research and experimentation to help.

EDIT:
I have found this on StackOverflow which demonstrates the exact same issue with UIKit. I am not sure how to implement their solution into this code but I will continue to research.

https://stackoverflow.com/questions/49098249/uitableview-jumps-between-positions-when-activating-and-deactivating-uisearchcon/49156726

Thanks

Errors when using in macOS SwiftUI app

Hey!

I've added the package to my macOS app that uses SwiftUI as per the instructions in the readme file. I do, however, get error messages when I try to build the application. This is a screenshot of the SwiftlySearch.swift file that shows up when I click on one of the 38 errors that I get:

Screenshot 2021-06-11 at 14 13 46

My project is set to macOS 11.3 as its target. Any idea what is going on?

High CPU usage

When using the search bar I get a high CPU usage (100% usage consistently), even when the user has not interacted with the search bar or the app at all. I only tested this on iOS 14.2.1.

Here is an example of how the high CPU usage can be reproduced quite easily:

import SwiftUI
import SwiftlySearch

class SearchViewModel: ObservableObject {
    @Published var searchText = ""
}

struct ContentView: View {
    
    @ObservedObject var viewModel = SearchViewModel()
    
    var body: some View {
        NavigationView {
            List {
                Text("foo")
            }.navigationBarSearch($viewModel.searchText)
        }
    }
}

As soon as the .navigationBarSearch is commented out, the high CPU usage disappears.

Am I doing something wrong here or could this be a bug?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.