SpotlightSearch 0.1.6

SpotlightSearch 0.1.6

Maintained by BRCountDownView.



SpotlightSearch

Spotlight Search UI written in SwiftUI and Combine.

Version License Platform

SpotlightSearch aims to provide macOS spotlight search UI/UX and beyond.

Screenshots

Alt Text Alt Text

SpotlightSearch Screenshot

Youtube video URL Link for how it works in dark mode:
link0

Youtube video URL Link for how it works in normal mode:
link0

At a Glance

// MARK: - Body
 var body: some View {
     SpotlightSearch(searchKeywords:viewModel.searchableItems,
               isSearching:$isSearching,
               didChangeSearchText: { self.viewModel.searchText = $0 },
               didTapSearchItem: { self.viewModel.searchText = $0 }) {
                 Text("Your view goes here")
     }
 }

Features

  • Written in SwiftUI and Combine 100%
  • It aims to provide quick and beautiful search UI/UX out of box like macOS Spotlight Search in iOS and beyond.
  • full geared toward MVVM.
  • target to be easy and simple to use API.

Example

To run the example project, clone the repo, and run pod install from the Example directory first. It includes examples for UIKit as well as SwiftUI.

Requirements

  • iOS 13.0 or later
  • Swift 5.0 or later
  • Xcode 11.0 or later

Getting Started

  • SwiftUI Simplified version. just copy and paste below code. It will work.
  1. clone repository
  2. Switch and select 'QuickExample' target.
  3. Build and run.

In 'QuickExample' directory, there are sample codes.

//
//  ContentView.swift
//  QuickExample
//
//  Created by Seoksoon Jang on 2019/12/05.
//  Copyright Β© 2019 Seoksoon Jang. All rights reserved.
//

import SwiftUI

/// Step1: πŸ˜† import `SpotlightSearch`!
import SpotlightSearch

struct ContentView: View {
    @State private var isSearching = false
    @ObservedObject var viewModel = TestViewModel()
    
    // MARK: - Body
    var body: some View {
        /// Step2: πŸ˜† Declare `Spotlight` externally.
        SpotlightSearch(searchKeywords:viewModel.searchableItems,
                  isSearching:$isSearching,
                  didChangeSearchText: { self.viewModel.searchText = $0 },
                  didTapSearchItem: { self.viewModel.searchText = $0 }) {
                    /// Step3: 😎 Let's wrap SwiftUI Views in it using trailing closure.
                    Button(action: {
                        withAnimation(.easeIn(duration: 0.3)) {
                            self.isSearching.toggle()
                        }
                    }) {
                        ZStack {
                            Image(systemName: "magnifyingglass")
                                .resizable()
                                .scaledToFit()
                                .frame(width: 80.0, height: 80.0)
                                .foregroundColor(.blue)
                        }

                    }
        }
    }
}

class TestViewModel: ObservableObject {
    @Published var searchText: String = ""
    @Published var searchableItems: [String] = ["Objective-C",
                                                "Clojure",
                                                "Swift",
                                                "Javascript",
                                                "Python",
                                                "Haskell",
                                                "Scala",
                                                "Rust",
                                                "C",
                                                "C++",
                                                "Dart",
                                                "C#",
                                                "F#",
                                                "LISP",
                                                "Golang",
                                                "Kotlin",
                                                "Java",
                                                "Assembly",
                                                "μ•ˆλ…•ν•˜μ„Έμš”",
                                                "κ°μ‚¬ν•©λ‹ˆλ‹€",
                                                "μ‚¬λž‘ν•©λ‹ˆλ‹€",
                                                "ν–‰λ³΅ν•˜μ„Έμš”"]
}
  • SwiftUI MVVM example code with basic networking operation using Combine. You need to set your own logic.
  1. clone repository
  2. Switch and Select 'SwiftUIExample' target
  3. build and run.

In SwiftExample directory, there are sample codes.

import SwiftUI

/// Step1: πŸ˜™ import `Spotlight`
import SpotlightSearch

struct ContentView: View {
    /// Assuming your viewmodel is like the example view model in the demo project, the way of how to use is as below.
    /// You can clone this repo then there is SwiftUIExample target demo project in it.
    @ObservedObject var viewModel: ItemListViewModel()
    @State private var isSearching = false
    
    // MARK: - Body
    var body: some View {
        /// Step2: πŸ˜† Declare `Spotlight` externally.
        SpotlightSearch(searchKeywords:viewModel.searchableItems,
                  isSearching:$isSearching,
                  didChangeSearchText: { self.viewModel.searchText = $0 },
                  didTapSearchItem: { self.viewModel.searchText = $0 }) {
                    /// Step3: 😎 Let's wrap SwiftUI Views in it using trailing closure.
                    self.navigationView
        }
    }
}

One Caveat

Currently, SpotlightSearch uses GLOBAL API to change UITableViewCell and UITableView property GLOBALLY like below since SwiftUI is in the very early stage of development and there are plenty of lack APIs out there and not possible to implement such UI Change while using SwiftUI 100%.

Take special care when applying SpotlightSearch into your app which might cause unexpected UI/UX change in your app. I will keep my eyes on the SwiftUI API change and when possible, I will fix this workaround as soon as released.

Note that SpotlightSearch uses these implementation in the initializer as below at the latest version.

// MARK: - Initializers
public init(searchKeywords: [String],
     isSearching: Binding<Bool>,
     didChangeSearchText: @escaping (String) -> Void,
     didTapSearchItem: @escaping (String) -> Void,
     wrappingClosure: @escaping () -> Content) {
    
    /// FIXME: THOSE GLOBAL THINGS MAY BE APPLIED TO ALL APP ALTHOUGH MODULE IS SEPARATED.
    /// BUT, THERE IS NO SUCH THING AS API BY WHICH I CAN MODIFY SWIFTUI.
    UITableView.appearance().allowsSelection = false
    UITableView.appearance().separatorStyle = .none
    UITableView.appearance().backgroundColor = .clear
    UITableView.appearance().tableFooterView = UIView()
    UITableView.appearance().contentInset = UIEdgeInsets(top:0,
                                                         left: 0,
                                                         bottom: 300,
                                                         right: 0)
    
    UITableViewCell.appearance().selectionStyle = .none
    UITableViewCell.appearance().backgroundColor = .clear
    
    self.content = wrappingClosure
    self._isSearching = isSearching
    
    self.didTapSearchItem = didTapSearchItem
    self.didChangeSearchText = didChangeSearchText
    
    self.spotlightSearchVM = SpotlightSearchVM(searchKeywords: searchKeywords,
                                               didChangeSearchText: didChangeSearchText)
}

Installation

There are two ways officially to use SpotlightSearch in your project:

  • using CocoaPods
  • using Swift Package Manager

Installation with CocoaPods

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the Get Started section for more details.

Podfile

First,

pod 'SpotlightSearch'

then in your root project,

pod install

Installation with Swift Package Manager (Xcode 11+)

Swift Package Manager (SwiftPM) is a tool for managing the distribution of Swift code as well as C-family dependency. From Xcode 11, SwiftPM got natively integrated with Xcode.

SpotlightSearch support SwiftPM from version 5.1.0. To use SwiftPM, you should use Xcode 11 to open your project. Click File -> Swift Packages -> Add Package Dependency, enter SpotlightSearch repo's URL. Or you can login Xcode with your GitHub account and just type SpotlightSearch to search.

After select the package, you can choose the dependency type (tagged version, branch or commit). Then Xcode will setup all the stuff for you.

If you're a framework author and use SpotlightSearch as a dependency, update your Package.swift file:

let package = Package(
    dependencies: [
        .package(url: "https://github.com/boraseoksoon/SpotlightSearch", from: "0.1.1")
    ],
    // ...
)

Author

[email protected]

License

SpotlightSearch is available under the MIT license. See the LICENSE file for more info.

References

PhotoCell : Time and Location-based photo browsing iOS app where you can download the photos and edit as you like for free.