YNSearch: a Pinterest-style search screen for iOS in Swift
๐ Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!
At a glance
- What is it?
- YNSearch is a Swift package that gives an iOS app a search screen with the layout people know from Pinterest, a category bar, search history and a result list, and the README goes further than most by publishing the whole view hierarchy so an app can replace the parts it wants. It was rewritten for Swift 6 in 2026 after a long gap since the Swift 5 release in 2019.
- Who is it for?
- Adopt YNSearch if you need a search screen with categories and history quickly in an iOS app and you are willing to take the view controller as the base class, because the library is built around inheritance rather than composition. Do not adopt it for a team that avoids UIKit subclassing, and do not expect it to cover a modern search experience on its own, since the highlighting comes from a separate library.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 40 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A search screen you inherit rather than build
YNSearch is described as an awesome, fully customisable search view that appears like the Pinterest search view, written in Swift with Realm support. The primary language of the repository is Swift, and the badges state the requirements plainly: Swift 6.0, iOS 13.0 or later, Swift Package Manager compatible, CocoaPods compatible, MIT licensed.
The README is explicit that Package.swift uses Swift tools 6.0, and that both Swift Package Manager and CocoaPods declare iOS 13.0 as the minimum deployment target. Two installation routes are given, the Add Package Dependencies dialog in Xcode with the repository URL, or a dependency clause:
dependencies: [
.package(url: "https://github.com/younatics/YNSearch.git", from: "3.0.0")
]and for CocoaPods a single line in the Podfile, pod 'YNSearch', '~> 3.0'.
What the library actually is, underneath, is a view controller with a search field, a category bar, a history area and a result table, and the interesting part of the design is that it is meant to be subclassed. The view hierarchy section in the README is not an afterthought, it is the documentation of the extension points.
Two phases: the view model first, the data second
The usage is split into two steps, and the order is not arbitrary.
First you give the search view its categories and, optionally, its search history:
import YNSearch
let demoCategories = ["Menu", "Animation", "Transition", "TableView"]
let demoSearchHistories = ["Menu", "Animation", "Transition", "TableView"]
let ynSearch = YNSearch()
ynSearch.setCategories(value: demoCategories)
ynSearch.setSearchHistories(value: demoSearchHistories)
ynSearchinit()Then you set the database, and the README is clear that the database and the key are both required. A YNSearchModel carries a key, which is what gets displayed in the result list:
let database1 = YNSearchModel(key: "YNDropDownMenu")
let database2 = YNSearchModel(key: "YNSearchData")
let demoDatabase = [database1, database2]
initData(database: demoDatabase)The database is an array of Any, and the README says you can use that to customise what you put in it. That is the seam the library leaves open: the model is a key, and anything else you want to search over you supply yourself as the object behind the key.
The categories and the history are therefore two different things, and they are configured at different times, which is why they appear in separate steps.
The delegate gives you the key and the object
The result list is a plain table view with a delegate, and the delegate protocol is where an application hooks in.
The two delegate methods you implement are the cell provider and the selection handler, and the selection handler is the interesting one because it hands you two things:
func ynSearchListView(_ ynSearchListView: UITableView, didSelectRowAt indexPath: IndexPath) {
let listView = self.ynSearchView.ynSearchListView
if let model = listView.searchResultDatabase[indexPath.row] as? YNSearchModel, let key = model.key {
// Call listview clicked based on key
listView.ynSearchListViewDelegate?.ynSearchListViewClicked(key: key)
// return object you set in database
listView.ynSearchListViewDelegate?.ynSearchListViewClicked(object: model)
// Append Search history
listView.ynSearch.appendSearchHistories(value: key)
}
}Two callbacks, one with the key string and one with the object, so an application can route on a stable identifier while still receiving the payload it stored. The third line is the piece of behaviour the library handles for you, appending the selection to the search history, which is why the history exists at all.
The cell provider is the ordinary dequeue-and-configure code, with a comment that names the reuse identifier.
There is also a separate YNSearchDelegate with four callbacks, for the history button, the category button, and the two list view clicks, which is the interface to set when you want the search view to notify you rather than to be used directly.
Realm support, and the conversion it demands
The Realm section is short and has an honest warning in it. You get your data with Realm, and then:
Realm is not collection type so you need to convert it again with [Any] type. This will find all string in your RealmModel and show you results.
let datas = realm.objects(RealmModel.self)and then the loop that turns the Realm results into the array the library expects:
var dataArray = [Any]()
for data in datas {
let searchModel = RealmModel()
searchModel.author = data.author
searchModel.detail = data.detail
searchModel.title = data.title
searchModel.type = data.type
dataArray.append(searchModel)
}
initData(database: dataArray)So the integration is a projection, not a live query. You copy the fields you want searchable into fresh model objects and hand those over, which means the library searches its own copy of the data rather than the Realm objects directly. That is a reasonable design for a UI component with a synchronous search model, and it is also the thing to notice, because the copy can drift from the store.
The README also credits Objectification, a separate library by the same author, for accurate search results, explaining that it gets all the data in your object and searches it. The companion library, not the search view itself, is what does the matching.
The view hierarchy, published as the extension guide
The README prints the view hierarchy of the library, which is unusual and useful, because it tells an integrator exactly what they are subclassing and what they can replace.
The top is YNSearchViewController, which you inherit. Under it sits YNSearchTextFieldView, a text field with a cancel button that is shown when the text field begins editing. Then YNSearchView, which holds the two halves the user sees. YNSearchMainView is the first visible view, with a category label, the YNCategoryButton row, a search history label, and the YNSearchHistoryView holding YNSearchHistoryButton items and a close button. YNSearchListView is the table view with the search results.
So the composition is one view controller, a search field area, a main view with categories and history, and a list. Every one of those is a named type you can reach into.
The customisation section follows from that, with the YNSearchDelegate set for callbacks, and a single call that changes the look of the category buttons:
setYNCategoryButtonType(type: .colorful)The README closes the customisation section by saying you can fully customise this YNSearch based on the view hierarchy, and the demo application is linked for more usage. The companion library Highlighter is pointed at for highlighting the search result.
Where YNSearch is the wrong choice
The first wrong-tool case is a team that avoids UIKit view controller subclassing. The library's model is inheritance, you are expected to inherit YNSearchViewController and reach into a fixed hierarchy of subviews. That is a reasonable choice for a component library written by one author, and it is a difficult fit for a codebase that has standardised on composition, on SwiftUI, or on a coordinator pattern that owns navigation.
The second is a search experience that needs more than filtering a local array. The library searches the data you hand it, in memory, and the accurate matching comes from the separate Objectification library. A search that has to query a server, rank results, handle synonyms or deal with a large corpus is a different piece of work, and the search view here would be the presentation layer of it at best.
The third is an application that has already committed to a design system. The category buttons and the history view come with their own appearance, and the one-line restyle is a type switch rather than a theming system. Retrofitting it means working inside a hierarchy somebody else designed.
There is also the maintenance question, and here the dates matter. The release list shows 3.0.0 in July 2026 described as a Swift 6 modernisation, 2.4.0 in March 2019 for Swift 5.0 support, and 2.3.2 in October 2018 for Swift 4.2. The gap between 2019 and 2026 is seven years, which is a long time for a UI component, and the 3.0.0 release is a rewrite to a new language mode rather than an incremental improvement.
MIT, a Swift 6 rewrite and a very old changelog
YNSearch is available under the MIT licence, with the LICENSE file at the repository root and the author named as younatics. The homepage listed for the component is on the CocoaControls site.
The repository layout is a conventional Xcode project with the sources in YNSearch/, a demo application in YNSearchDemo/, the project file YNSearch.xcodeproj/, a podspec, a Package.swift for SwiftPM, a Tests/ directory, Images/ for the screenshots the README uses, and a CHANGELOG.md that the Updates section points to. There is also a.travis.yml, which dates the continuous integration to the era when the project was on Travis rather than GitHub Actions.
The 3.0.0 release is described as a Swift 6 modernisation, and the version jump from 2.4.0 to 3.0.0 in line with that is a major version for a reason. Anyone upgrading from the 2.x line is looking at a component that was rewritten for a new language mode, and the changelog is where they will find out what changed.
The related projects are worth knowing about, since the search functionality is split across them. Highlighter handles highlighting the search result, Objectification does the matching by reaching into the object's data, and MotionBook is the third in the set.
Editorial conclusion
Adopt YNSearch if you need a search screen with categories and history quickly in an iOS app and you are willing to take the view controller as the base class, because the library is built around inheritance rather than composition. Do not adopt it for a team that avoids UIKit subclassing, and do not expect it to cover a modern search experience on its own, since the highlighting comes from a separate library. Before you integrate, read the 3.0.0 changelog entry, because the Swift 6 modernisation is a large jump from the 2.4.0 release of 2019, and check the delegate and history handling in the demo before you rely on the behaviour.
Frequently asked questions
What does the YNSearch library provide?
A fully customisable iOS search view that appears like the Pinterest search view, written in Swift, with a search field and cancel button, a category bar, a search history area and a result table view, plus an optional Realm integration for populating the search database.
How do I install YNSearch?
Through Swift Package Manager, by adding the repository in Xcode with Add Package Dependencies or with a dependency clause using from: "3.0.0", or through CocoaPods with pod 'YNSearch', '~> 3.0'. The library uses Swift 6.0 and requires iOS 13.0 or later, and Package.swift uses Swift tools 6.0.
How is data loaded into the YNSearch view?
You set the categories and, optionally, the search history on the YNSearch instance, then build an array of YNSearchModel values, each with a key that is displayed in the result list, and pass that array to initData with the database argument. The database is typed as [Any] so you can store your own objects behind the keys.
Does YNSearch support Realm?
Yes, with a caveat the README states plainly: Realm is not a collection type, so you must convert the results to [Any] yourself, copying the fields you want searchable into new model objects before passing them to initData.
What licence is YNSearch released under?
MIT, with the LICENSE file at the repository root. The most recent release is 3.0.0 from 2026-07-07, described as a Swift 6 modernisation, and the previous releases were 2.4.0 in March 2019 and 2.3.2 in October 2018, so the last push was on 2026-09-13.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/younatics-ynsearch)Was this useful?