⚡️ A library of widgets and helpers to build instant-search applications on iOS.

Overview

InstantSearch iOS

Pod Version Pod Platform Carthage compatible SwiftPM compatible Mac Catalyst compatible Licence

By Algolia.

InstantSearch family: InstantSearch iOS | InstantSearch Android | React InstantSearch | InstantSearch.js | Angular InstantSearch | Vue InstantSearch.

InstantSearch iOS is a framework providing components and helpers to help you build the best instant-search experience on iOS with Algolia. It is built on top of Algolia's Swift API Client library to provide you a high-level solution to quickly build various search interfaces.

Structure

InstantSearch iOS consists of three products

  • InstantSearch Insights – library that allows developers to capture search-related events
  • InstantSearch Core – the business logic modules of InstantSearch without provided UIKit controllers
  • InstantSearch – the complete InstantSearch toolset including UIKit and SwiftUI components

Demo

You can see InstantSearch iOS in action in our Examples repository, in which we published search experiences built with InstantSearch and written in Swift:

Installation

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. Since the release of Swift 5 and Xcode 11, SPM is compatible with the iOS, macOS and tvOS build systems for creating apps.

To use SwiftPM, you should use Xcode 11 to open your project. Click File -> Swift Packages -> Add Package Dependency, enter InstantSearch repo's URL. Next, select the products you consider to use in your project from the provided list.

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

let package = Package(
    // 7.11.0 ..< 8.0.0
    dependencies: [
        .package(url: "https://github.com/algolia/instantsearch-ios", from: "7.11.0")
    ],
    // ...
)

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

To install InstantSearch, simply add the following line to your Podfile:

pod 'InstantSearch', '~> 7.11'
# pod 'InstantSearch/Insights' for access to Insights library only
# pod 'InstantSearch/Core' for access business logic without UIKit components
# pod 'InstantSearch/SwiftUI' for access to SwiftUI components

Then, run the following command:

$ pod update

Carthage

Carthage is a simple, decentralized dependency manager for Cocoa.

  • To install InstantSearch, simply add the following line to your Cartfile:
github "algolia/instantsearch-ios" ~> 7.11
  • Launch the following commands from the project directory
carthage update
./Carthage/Checkouts/instant-search-ios/carthage-prebuild
carthage build

NOTE: At this time, Carthage does not provide a way to build only specific repository subcomponents (or equivalent of CocoaPods's subspecs). All components and their dependencies will be built with the above command. However, you don't need to copy frameworks you aren't using into your project. For instance, if you aren't using UI components from InstantSearch, feel free to delete that framework from the Carthage Build directory after carthage update completes keeping only InstantSearchCore. If you only need event-tracking functionalities, delete all but InstantSearchInsights framework.

If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained over at Carthage.

Documentation

You can start with the Getting Started Guide.

Learn more about instantSearch iOS in the dedicated documentation website.

Basic Usage

In your ViewController.swift:

import InstantSearch

struct BestBuyItem: Codable {
  let name: String
}

struct BestBuyTableViewCellConfigurator: TableViewCellConfigurable {
   
  let model: BestBuyItem
  
  init(model: BestBuyItem, indexPath: IndexPath) {
    self.model = model
  }
  
  func configure(_ cell: UITableViewCell) {
    cell.textLabel?.text = model.name
  }

}

typealias BestBuyHitsViewController = HitsTableViewController<BestBuyTableViewCellConfigurator>

class ViewController: UIViewController {
      
  let searcher = SingleIndexSearcher(appID: "latency",
                                     apiKey: "1f6fd3a6fb973cb08419fe7d288fa4db",
                                     indexName: "bestbuy")
  lazy var searchController: UISearchController = .init(searchResultsController: hitsTableViewController)
  lazy var searchConnector: SingleIndexSearchConnector<BestBuyItem> = .init(searcher: searcher,
                                                                            searchController: searchController,
                                                                            hitsController: hitsTableViewController)
  let hitsTableViewController: BestBuyHitsViewController = .init()
  let statsInteractor: StatsInteractor = .init()
  
  override func viewDidLoad() {
    super.viewDidLoad()
    searchConnector.connect()
    statsInteractor.connectSearcher(searcher)
    statsInteractor.connectController(self)
    searcher.search()
    setupUI()
  }
  
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    searchController.searchBar.becomeFirstResponder()
  }
  
  func setupUI() {
    view.backgroundColor = .white
    navigationItem.searchController = searchController
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.showsSearchResultsController = true
    searchController.automaticallyShowsCancelButton = false
  }
      
}

extension ViewController: StatsTextController {
  
  func setItem(_ item: String?) {
    title = item
  }

}

Run your app and you will the most basic search experience: a UISearchBar with the number of results each time you write a query.

To get a more meaningful search experience, please follow our Getting Started Guide.

If you only require business logic modules in your project and use InstantSearchCore framework, add import InstantSearchCore to your source files.

Insights

InstantSearch Insights iOS library allows developers to capture search-related events. The events maybe related to search queries (such as click an conversion events used for Click Analytics or A/B testing). It does so by correlating events with queryIDs generated by the search API when a query parameter clickAnalytics=true is set. As well library allows to capture search-independent events which can be used for the purpose of search experience personalization. There are three types of these events which are currently supported: click, conversion and view.

Quick Start

Initialize the Insights client

You first need to initialize the Insights client. For that you need your Application ID and API Key. You can find them on your Algolia account. Also, for the purpose of personalization an application User Token can be specified via the corresponding optional parameter. In case of non-specified user token an automatically-generated application-wide user token will be used.

Insights.register(appId: "testApp", apiKey: "testKey", userToken: "testToken")

Sending metrics

Once that you registered your Application ID and the API Key you can easily start sending metrics.

Insights.shared?.clickedAfterSearch(eventName: "click event",
                                    indexName: "index name",
                                    objectID: "object id",
                                    position: 1,
                                    queryID: "query id")

Insights.shared?.convertedAfterSearch(eventName: "conversion event",
                                      indexName: "index name",
                                      objectIDs: ["obj1", "obj2"],
                                      queryID: "query id")

Insights.shared?.viewed(eventName: "view event",
                        indexName: "index name",
                        filters: ["brand:apple"])

Logging and debuging

In case you want to check if the metric was sent correctly, you need to enable the logging first

Insights.shared(appId: "appId")?.isLoggingEnabled = true

After you enabled it, you can check the output for success or error messages

Events flush delay

By default the client transmits tracked events every 30 seconds. You can customize this delay by changing flushDelay value (in seconds) as follows:

Insights.flushDelay = 60

Setting API region

By default each analytics API call is geo-routed so that each call targets the closest API. Today the analytics API suports two regions: United States and Germany. You can specify the region your prefer to use as follows:

Insights.region = .de

Getting Help

  • Need help? Ask a question to the Algolia Community or on Stack Overflow.
  • Encountering an issue? Before reaching out to support, we recommend heading to our FAQ where you will find answers for the most common issues and gotchas with the framework.
  • Found a bug? You can open a GitHub issue.
  • Questions about Algolia? You can search our FAQ in our website.

Getting involved

  • If you want to contribute please feel free to submit pull requests.
  • If you have a feature request please open an issue.
  • If you use InstantSearch in your app, we would love to hear about it! Drop us a line on discourse or twitter.

License

InstantSearch iOS is Apache 2.0 licensed.

Comments
  • Unable to display categories selected data in list page

    Unable to display categories selected data in list page

    Here I am using the algolia for the first time to display the categories selected id to pass and load data in list page according to it and here I passed the selected data to the list page but here unable to load the data required for selected category and got crashed in index.search line please help me how to resolve this ?

    Here is my selected categories array data which I was passing from my categories page

    ["[categories.level0:Men]", "[categories.level1:Men///Tops]", "[categories.level2:Men///Tops///Tees]"]

    and below is my facets array data

    ["categories.level0", "categories.level1", "categories.level2", "gometoo_seller", "style_bottom", "climate", "sleeve", "gender", "category_gear", "eco_collection", "pattern", "collar", "style_bags", "style_general", "is_trending", "erin_recommends", "format", "performance_fabric", "strap_bags", "features_bags", "activity", "material", "categories", "color", "is_new", "size", "price", "manufacturer", "price.BHD.default", "price.EGP.default", "price.EUR.default", "price.KWD.default", "price.OMR.default", "price.SAR.default", "price.USD.default", "price.AED.default"]

    here is my algolia back end data

    index.search("", {
     "hitsPerPage": "10",
     "page": "0",
     "analytics": "false",
     "attributesToRetrieve": "*",
     "facets": "[\"categories.level0\",\"categories.level1\",\"categories.level2\",\"activity\",\"category_gear\",\"climate\",\"color\",\"eco_collection\",\"erin_recommends\",\"features_bags\",\"format\",\"gender\",\"gometoo_seller\",\"is_new\",\"is_trending\",\"material\",\"pattern\",\"performance_fabric\",\"price.AED.default\",\"price.BHD.default\",\"price.EGP.default\",\"price.EUR.default\",\"price.KWD.default\",\"price.OMR.default\",\"price.SAR.default\",\"price.USD.default\",\"size\",\"strap_bags\",\"style_bags\",\"style_bottom\",\"style_general\"]",
     "facetFilters": "[[\"categories.level2:Men /// Tops /// Tees\"],[\"categories.level1:Men /// Tops\"],[\"categories.level0:Men\"]]"
    });
    

    and the code for this is

    if (self.appId != nil && self.apiKEY != nil && self.Indices != nil) {
                InstantSearch.shared.configure(appID: "\(self.appId!)", apiKey: "\(self.apiKEY!)", index: "\(self.Indices!)en_products")
                InstantSearch.shared.params.attributesToRetrieve = ["*"]
                InstantSearch.shared.registerAllWidgets(in: self.view)
                let query = Query()
                query.facets = facetsArray
                query.facetFilters = categoriesArray
                index.search(query, completionHandler: { (res, error) in
                    self.listCollectionView.reloadData()
                })
                hitsCollectionViews = [self.listCollectionView]
                ActivityIndicator.stopAnimating()  
            }
    
    opened by vamsikrishnasurathi 14
  • Filter.Numeric not working with large integer (i.e. timestamps)

    Filter.Numeric not working with large integer (i.e. timestamps)

    Describe the bug 🐛 I have a date_timestamp in my index, and would like to add a Filter.Numeric to my FilterState. The filter is not respected and no results is returned.

    To Reproduce 🔍

    let nowTimestamp = Float(NSDate().timeIntervalSince1970)
    let filter = Filter.Numeric(attribute: "date_timestamp", operator: .greaterThanOrEqual, value: nowTimestamp)
    filterState[and: "calendar"].add(filter)
    ...
    

    This doesn't returns any results as it should be, based on my index data.

    Expected behavior 💭 The filter should returns the correct answer.

    Environment:

    • OS: iOS
    • Version 5.2.2
    opened by aplusm 11
  • Xcode 13 beta - error: Segmentation fault: 11 (in target 'InstantSearchInsights' from project 'InstantSearch')

    Xcode 13 beta - error: Segmentation fault: 11 (in target 'InstantSearchInsights' from project 'InstantSearch')

    Describe the bug 🐛 When build on Xcode Beta 13, Xcode won't build and gives this error: error: Segmentation fault: 11 (in target 'InstantSearchInsights' from project 'InstantSearch')

    Screenshots 🖥 Screenshot 2021-06-08 at 12 26 23

    Environment: macOS Big Sur 11.4 (20F71)

    opened by alelordelo 10
  • Xcode 12.5 (Fastlane) Archive Fails

    Xcode 12.5 (Fastlane) Archive Fails

    Describe the bug 🐛 Building fails with "unknown type" errors (see screenshot) that suggest the compiler doesn't realize you're referencing SwiftUI for some reason. While this seems like it might be a compiler bug, an easy fix is to add import SwiftUI statements to any files requiring it.

    To Reproduce 🔍 Steps to reproduce the behavior:

    1. Attempt to archive a build via Fastlane including this project vis SPM.
    2. Building and archiving fails.

    Expected behavior 💭 Builds should succeed.

    Screenshots 🖥 Screen Shot 2021-05-08 at 6 44 22 PM

    Environment:

    • OS: iOS
    • Version 7.11.0
    opened by Sam-Spencer 8
  •  Unrecognized Selector Sent To Instance - Sequencer Class

    Unrecognized Selector Sent To Instance - Sequencer Class

    I am using InstantSearch MultiIndex components and I am getting a crash that occurs every now and then. App crashes and returns "unrecognized selector sent to instance" error. I set a breakpoint and see that it ends up crashing in the dismissOperation(withSeqNo seqNo: Int) function in the Sequencer class. When not setting a breakpoint, I also get the following error:

    Thread. 3: EXC_BAD_ACCESS (code=1, address=0x18) in the cancelOperation(withSeqNo seqNo: Int) function in the Sequencer class.

    In the view controller, I am using a MultiIndexSearcher, MultiIndexSearchConnector, MultiIndexHitsInteractor, and a MultiIndexHitsController to perform the search. I have a search controller to handle user input. I eliminated everything else in the viewcontroller except these Instant Search Components

    The crash only happens about 1 in 8 times. It will work as expected for a couple of builds, and then will crash with the above error every now in then.

    I am using iOS 14. I can provide additional details if needed.

    opened by RichieViscardi 6
  • Application rejected due to NSSpeechRecognitionUsageDescription

    Application rejected due to NSSpeechRecognitionUsageDescription

    Kindly someone guide me regarding this one, i've added NSSpeechRecognitionUsageDescription key in info.plist but still getting rejected. Apple response is as following.  

      Dear Developer,We identified one or more issues with a recent delivery for your app, "App Name". Please correct the following issues, then upload again.Missing Purpose String in Info.plist File - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSSpeechRecognitionUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data will be required to include a purpose string.If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more (https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).Best regards,The App Store Team

    opened by azharashiq178 6
  • Cannot Build InstantSearch Using Carthage

    Cannot Build InstantSearch Using Carthage

    Describe the bug 🐛 Attempting to build the instantsearch-ios library using Carthage produces a build failure when building the InstantSearchTelemetry framework.

    To Reproduce 🔍 Steps to reproduce the behavior:

    1. Create a Cartfile containing github "algolia/instantsearch-ios".
    2. Run carthage update --no-build to checkout the dependency projects.
    3. Run chmod u+x Carthage/Checkouts/instantsearch-ios/carthage-prebuild to allow carthage-prebuild to be executed.
    4. Run ./Carthage/Checkouts/instantsearch-ios/carthage-prebuild.
    5. Run carthage build --platform iOS --use-xcframeworks.
    6. A build failure occurs. The log output for the error shows:
    import SwiftProtobuf
           ^
    
    ** ARCHIVE FAILED **
    
    
    The following build commands failed:
    	CompileSwift normal armv7 (in target 'InstantSearchTelemetry' from project 'InstantSearchTelemetry')
    	CompileSwiftSources normal armv7 com.apple.xcode.tools.swift.compiler (in target 'InstantSearchTelemetry' from project 'InstantSearchTelemetry')
    	CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler (in target 'InstantSearchTelemetry' from project 'InstantSearchTelemetry')
    	CompileSwift normal arm64 (in target 'InstantSearchTelemetry' from project 'InstantSearchTelemetry')
    (4 failures)
    
    1. Opening Carthage/Checkouts/instantsearch-telemetry-native/InstantSearchTelemetry.xcodeproj and attempting a build for an iOS Simulator gives the following build error:
    Screenshot 2022-04-28 at 12 15 01

    Expected behavior 💭 The InstantSearch iOS framework and its dependency frameworks should be built successfully. Note that following the above steps with a Cartfile containing github "algolia/algoliasearch-client-swift" works as expected.

    Environment:

    • OS: macOS 12.3.1
    • Xcode 13.2.1
    • Carthage 0.38.0
    opened by steve-wiggle 5
  • InstantSearch not working with Swift 5.5

    InstantSearch not working with Swift 5.5

    Describe the bug 🐛 I am not able to import InstantSearch with Swift 5.5. I get the following errors. -Could not find module 'InstantSearch' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator -Module compiled with Swift 5.4 cannot be imported by the Swift 5.5 compiler: To Reproduce 🔍 Steps to reproduce the behavior:

    1. Add InstantSearch to your Project
    2. import InstantSearch

    Expected behavior 💭 You should be able to import and use InstantSearch

    Screenshots 🖥

    Environment:

    • InstantSearch iOS 7.13.5
    • Xcode 13 on ARM Mac running macOS Big Sur
    • I used CocoaPods and also tried with Swift Package Manager
    opened by devJAdam 5
  • Compiler error Xcode 12

    Compiler error Xcode 12

    After installing the "InstantSearch" via CocoaPods, I am unable to run my project, and it's showing three build errors upon installing the pod.

    Screen Shot 2020-12-23 at 6 22 13 PM
    opened by ferrlan 5
  • How to add parameters before search() ?

    How to add parameters before search() ?

    I am adding a parameter to Searcher like this :

    InstantSearch.shared.getSearcher().params.filters = "application_categories:69539"
    InstantSearch.shared.getSearcher().search()
    

    On the results, this params is not taken in account.

    Here is the debug result. The filter appears in the Searcher params :

    (lldb) po InstantSearch.shared.getSearcher().params
    SearchParameters{["hitsPerPage": "20", "attributesToHighlight": "[\"name\"]", 
    "attributesToRetrieve": "[\"name\",\"description\",\"best_offer\",\"brand\",\"assigned_images\",\"created_on\",
    \"offers_count\",\"other_offers\",\"application_categories_dict\"]", "filters": "application_categories:69539"]}
    

    Can any one please tell me how can I add parameter to the InstantSearch ?

    opened by Geoffrey63 5
  • Incorrect number of hits on HitsInteractor when using pagination (infinitescroll)

    Incorrect number of hits on HitsInteractor when using pagination (infinitescroll)

    Describe the bug 🐛 With infinitescroll the HitsInteractor returns an incorrect number of hits after query is changed with hits less than the previous one.

    To Reproduce 🔍 Steps to reproduce the behavior:

    Pre-req: On example project, configure Paging Single Index to support applying of filter that will return less hits than the default

    1. Go to Paging Single Index
    2. Scroll down to at least 3 pages or more (roughly you'll be at numberOfHits=80 and above)
    3. Apply filter (this filter should have a result that is less than the number of hits pre-filter)
    4. See error.

    Expected behavior 💭 HitsInteractor.numberOfHits should return the numbers from step 3 but it returns step 2 numbers.

    Here's a demo video: https://user-images.githubusercontent.com/81630747/195762256-fada5382-119f-4eb6-ba82-4fdf141a1080.mov Note: On the demo, I'm using our own indices.

    Environment:

    • OS: iOS
    • Version: 15.5
    • InstantSearch: 7.21

    Additional context

    • Seems like it only happens when you've loaded other pages. If you skip step 2, bug doesn't occur.
    • With the bug, you'll encounter a scenario wherein HitsInteractor.numberOfHits is more than SearchStat.totalNumberOfHits. As a result, it messes up the UI. As a temp solution, I had to create a conditional check like this to determine the correct item count to display
      if hitsSource.numberOfHits() > stats.totalHitsCount {
          return stats.totalHitsCount
      }
       return hitsSource.numberOfHits()
    
    opened by steffidg 4
  • Expose text field background / foreground colors to enable dark mode support

    Expose text field background / foreground colors to enable dark mode support

    Summary

    The text field background and foreground color for the main search bar component is not dark mode aware, so this PR exposes them for 3rd party developers to override and customize.

    Result

    The Xcode project in this repository seems to require special local configuration in order to build from the project file, so I opened the Package.swift file and made sure the changes built using the package declarations (which it did).

    Also I made a minor update to specify the generic type of the button label in order to satisfy Swift's compiler in Xcode 13.4.1 which could not figure out the Button's label type. If you find this unnecessary I'm happy to remove it.

    opened by msmollin 1
  • InstantSearch iOS Numeric Range Iteractor/Connector not refreshing when searcher search changed

    InstantSearch iOS Numeric Range Iteractor/Connector not refreshing when searcher search changed

    Describe the bug 🐛 Problem with NumberRangeInteractor and NumberRangeObservableController When an initial search is done, the right values are found. But after, if I am doing another search with a different text, the range does not change!!

    Expected behavior 💭 The new query is taken into account for the new values of the range

    Environment:

    • OS: iOS - SwiftUI
    • Version device: 15.4.1
    • Version SDK Algolia: InstantSearch v7.17.0

    Additional context For a marketplace type application on iOS, I am adding functionalities such as selectable segment, hierarchical categories, dynamic facets and a Range Slider for the price. I also have a search bar for searching. Works well for all EXCEPT the Range Slider. When an initial search is done, the right values are found. But after, if I am doing another search with a different text, the range does not change!!

    I have this numericRangeInteractor that I connected to my FilterState and searcher, and finally my controller (NumericRangeController) For info I have connector my Numeric Range Interactor this following way take the traditional RangeSlider as my slider.

            priceNumberRangeInteractor.connectFilterState(filterState, attribute: "c_price_int")
            priceNumberRangeInteractor.connectSearcher(searcher, attribute: "c_price_int")
            priceNumberRangeInteractor.connectController(priceNumberRangeController)
    

    Any idea? I tested everything. Thanks !!!

    opened by DrikABrak 1
  • Documentation Request

    Documentation Request

    I see that queryInputInteractor.connectSearcher has been extended with a new method:

    @discardableResult func connectSearcher<Service: SearchService>(_ searcher: AbstractSearcher<Service>,
                                                                      searchTriggeringMode: SearchTriggeringMode = .searchAsYouType) -> TextualQuerySearcherConnection<Service> {
        let connection = TextualQuerySearcherConnection(interactor: self, searcher: searcher, searchTriggeringMode: searchTriggeringMode)
        connection.connect()
        return connection
      }
    

    Is there any documentation on how to pass in an AbstractSearcher? I'm currently using the original implementation and I'm seeing a deprecation warning from:

    @available(*, deprecated, message: "Use QueryInputInteractor.TextualQuerySearcherConnection")
      @discardableResult func connectSearcher<S: Searcher>(_ searcher: S,
                                                           searchTriggeringMode: SearchTriggeringMode = .searchAsYouType) -> SearcherConnection<S> {
        let connection = SearcherConnection(interactor: self, searcher: searcher, searchTriggeringMode: searchTriggeringMode)
        connection.connect()
        return connection
      }
    

    I wish this SDK had better documentation, either on the website or in this repo, thanks.

    opened by leojkwan 0
Releases(7.21.2)
Owner
Algolia
Open source tools for building search. Learn more at community.algolia.com
Algolia
Search jailbreak packages using the Tweakio API, Parcility API or Canister API straight from Cydia, Installer, Sileo and Zebra!

Tweakio Search packages globally directly from your favourite package manager! Works with Cydia, Installer, Zebra and Sileo! How does it work The twea

null 17 Jan 1, 2023
App that uses iTunes Search API with SwiftUI for iOS 15+

ItunesSearchApp App that uses iTunes Search API with SwiftUI for iOS 15+ Documentation iTunes Search API: https://developer.apple.com/library/archive/

Karin Prater 22 Dec 25, 2022
Reel Search is a Swift UI controller that allows you to choose options from a list

REEL SEARCH Reel Search is a Swift UI controller that allows you to choose options from a list We specialize in the designing and coding of custom UI

Ramotion 2.5k Dec 21, 2022
🔍 Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
Safari Web Extension to customize your search engine.

Safari Web Extension to customize your search engine. Search queries made from the Safari address bar are appended to the custom search engine URL. No

Marvin Häuser 3 Nov 16, 2022
A draggable modal for iOS Applications.

Mantle Modal Draggable Modal, PopUp or Menu written in Swift. Description A simple modal resource that uses a UIScrollView to allow the user to close

Ricardo Canales 89 Feb 25, 2022
Material, a UI/UX framework for creating beautiful iOS applications

Material Welcome to Material, a UI/UX framework for creating beautiful applications. Material's animation system has been completely reworked to take

Cosmicmind 12k Jan 2, 2023
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.

kishikawakatsumi/SpreadsheetView has moved! It is being actively maintained at bannzai/SpreadsheetView. This fork was created when the project was mov

Kishikawa Katsumi 34 Sep 26, 2022
Easily use UIKit views in your SwiftUI applications. Create Xcode Previews for UIView elements

SwiftUIKitView Easily use UIKit views in SwiftUI. Convert UIView to SwiftUI View Create Xcode Previews from UIView elements SwiftUI functional updatin

Antoine van der Lee 682 Dec 29, 2022
UI framework that allows developers to integrate an amazing selection interface into their applications

UI framework that allows developers to integrate an amazing selection interface into their applications! Each bubble has a set of parameters, which could be configured individually.

AJIJIi 5 Jul 12, 2022
BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen

BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen. It is especially well

Alexis (Aubry) Akers 5.3k Jan 2, 2023
StarryStars is iOS GUI library for displaying and editing ratings

StarryStars StarryStars is iOS GUI library for displaying and editing ratings Features StarryStars' RatingView is both IBDesignable and IBInspectable

Peter Prokop 175 Nov 19, 2022
A drop-in universal library helps you to manage the navigation bar styles and makes transition animations smooth between different navigation bar styles

A drop-in universal library helps you to manage the navigation bar styles and makes transition animations smooth between different navigation bar styles while pushing or popping a view controller for all orientations. And you don't need to write any line of code for it, it all happens automatically.

Zhouqi Mo 3.3k Dec 21, 2022
Powerful and easy-to-use vector graphics Swift library with SVG support

Macaw Powerful and easy-to-use vector graphics Swift library with SVG support We are a development agency building phenomenal apps. What is Macaw? Mac

Exyte 5.9k Jan 1, 2023
Lightweight touch visualization library in Swift. A single line of code and visualize your touches!

TouchVisualizer is a lightweight pure Swift implementation for visualising touches on the screen. Features Works with just a single line of code! Supp

Morita Naoki 851 Dec 17, 2022
Wallet is a library to manage cards and passes.

Wallet Wallet is a replica of the Apple's Wallet interface. Add, delete or present your cards and passes. Feel free to use this pod in your project an

Russ St Amant 360 Feb 4, 2022
ScrollViewPlus is a small library that provides some helpful extension and capabilities for working with NSScrollView.

ScrollViewPlus is a small library that provides some helpful extension and capabilities for working with NSScrollView.

Chime 12 Dec 26, 2022
A highly configurable and out-of-the-box-pretty UI library

We absolutely love beautiful interfaces! As an organization named Unicorn, we are obligated to be unique and majestic.

Clayton (McIlrath) Unicorn 225 Feb 11, 2022