Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/aheze/SupportDocs into main
Browse files Browse the repository at this point in the history
  • Loading branch information
aheze committed Dec 11, 2020
2 parents 8efe68c + 0f0ff90 commit c58f17a
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 99 deletions.
40 changes: 0 additions & 40 deletions Sources/SupportDocs/SupportDocsView+Search.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,6 @@

import SwiftUI


/**
Search bar at the top of the NavigationView.

Source: [http://blog.eppz.eu/swiftui-search-bar-in-the-navigation-bar/]( http://blog.eppz.eu/swiftui-search-bar-in-the-navigation-bar/).

MIT License
*/
internal class SearchBarConfigurator: NSObject, ObservableObject {

/// The text inside the search bar.
@Published var searchText: String = ""

/// Instance of the search controller.
let searchController: UISearchController = UISearchController(searchResultsController: nil)

override init() {
super.init()

/// Prevent a gray overlay over the list.
self.searchController.obscuresBackgroundDuringPresentation = false

/// Set the delegate.
self.searchController.searchResultsUpdater = self
}
}

/**
Delegate method of `UISearchController`
*/
extension SearchBarConfigurator: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {

/// Publish search bar text changes.
if let searchBarText = searchController.searchBar.text {
self.searchText = searchBarText
}
}
}

/**
View Modifier for applying the search bar.
*/
Expand Down
52 changes: 31 additions & 21 deletions Sources/SupportDocs/SupportDocsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@ public struct SupportDocsView: View {
This is only for SwiftUI -- You don't need to do this in UIKit. As long as you set `options.navigationBar.dismissButtonTitle = "Dismiss"`, SupportDocs will dismiss itself.
*/
public init(dataSourceURL: URL, options: SupportOptions = SupportOptions(), isPresented: Binding<Bool>? = nil) {

/**
The custom `NavigationConfigurator` modifier only works for iOS 14 and above, so for lower versions set `UINavigationBar.appearance()` instead.
*/
if #available(iOS 14.0, *) { } else {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.titleTextAttributes = [.foregroundColor: options.navigationBar.titleColor]
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: options.navigationBar.titleColor]
navBarAppearance.backgroundColor = options.navigationBar.backgroundColor
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
UINavigationBar.appearance().standardAppearance = navBarAppearance
UINavigationBar.appearance().tintColor = options.navigationBar.buttonTintColor
}
self.dataSourceURL = dataSourceURL
self.options = options
self.isPresented = isPresented
Expand Down Expand Up @@ -111,43 +98,66 @@ public struct SupportDocsView: View {
*/
@State internal var sections: [SupportSection] = [SupportSection]()

/**
Reference of the search bar and its delegate.
*/
@ObservedObject var searchBarConfigurator = SearchBarConfigurator()

public var body: some View {
NavigationView {
Group {
ZStack {
if isDownloadingJSON {

/// Show the loading spinner if JSON is downloading.
ActivityIndicator(isAnimating: $isDownloadingJSON, style: options.other.activityIndicatorStyle)
} else {

List {

/// First, display the titles of your documents.
ForEach(sections) { section in
ForEach(

/// Filter the sections. Display only those that contain documents where their titles contain the search bar's text.
sections.filter { section in
return searchBarConfigurator.searchText.isEmpty || section.supportItems.contains(where: {
$0.title.localizedStandardContains(searchBarConfigurator.searchText)
})
}
) { section in
Section(header: Text(section.name)) {
ForEach(section.supportItems) { item in
ForEach(

/// Filter the documents in each section.
section.supportItems.filter { item in
return searchBarConfigurator.searchText.isEmpty || item.title.localizedStandardContains(searchBarConfigurator.searchText)
}
) { item in
SupportItemRow(
title: item.title,
titleColor: section.color,
url: URL(string: item.url) ?? options.other.error404,
progressBarOptions: options.progressBar
)
.animation(nil)
}
}
.displayTextAsConfigured() /// Prevent default all-caps behavior if possible (iOS 14 and above).
}

/// Then, display the footer. Customize this inside `options.other.footer`.
options.other.footer
.listRowInsets(EdgeInsets())
.frame(maxWidth: .infinity, minHeight: 60)
.background(Color(UIColor.systemGroupedBackground))
.listRowInsets(EdgeInsets())
.frame(maxWidth: .infinity, minHeight: 60)
.background(Color(UIColor.systemGroupedBackground))

}
.listStyle(for: options.listStyle) /// Set the `listStyle` of your selection.
.transition(.opacity) /// Fade the List in once the JSON loads.

}
}
.transition(.opacity) /// Fade it in once the JSON loads.
.navigationBarTitle(Text(options.navigationBar.title), displayMode: .large) /// Set your title.
.configureNavigationBarIfAvailable(navigationOptions: options.navigationBar)
.configureBar(for: options, searchBarConfigurator: searchBarConfigurator)

/**
If you have a dismiss button, display it.
Expand Down
121 changes: 121 additions & 0 deletions Sources/SupportDocs/SupportOptions/SupportOptions+SearchBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//
// SupportOptions+SearchBar.swift
// SupportDocsSwiftUI
//
// Created by Zheng on 11/28/20.
//

import UIKit
import SwiftUI
import Combine

public extension SupportOptions {

/**
Customize the appearance of the Search Bar.
*/
struct SearchBar {

/**
Customize the appearance of the Search Bar.

- parameter placeholder: The placeholder shown in the search bar before the user has entered text.
- parameter placeholderColor: Color of the placeholder and search icon.
- parameter textColor: Color of the search text.
- parameter tintColor: Color of the cursor and "Cancel" button.
- parameter backgroundColor: Background color of the search text field.
- parameter clearButtonMode: A mode that controls when the standard Clear button appears in the text field.
*/
public init(
placeholder: String = "Search",
placeholderColor: UIColor = UIColor.secondaryLabel.withAlphaComponent(0.75),
textColor: UIColor = UIColor.label,
tintColor: UIColor = UIColor.blue,
backgroundColor: UIColor = UIColor.white.withAlphaComponent(0.3),
clearButtonMode: UITextField.ViewMode = .whileEditing
) {
self.placeholder = placeholder
self.placeholderColor = placeholderColor
self.textColor = textColor
self.tintColor = tintColor
self.backgroundColor = backgroundColor
self.clearButtonMode = clearButtonMode
}


/**
The placeholder shown in the search bar before the user has entered text.
*/
public var placeholder: String = "Search"

/**
Color of the placeholder and search icon.
*/
public var placeholderColor: UIColor = UIColor.secondaryLabel.withAlphaComponent(0.75)

/**
Color of the search text.
*/
public var textColor: UIColor = UIColor.label

/**
Color of the cursor and "Cancel" button.
*/
public var tintColor: UIColor = UIColor.blue

/**
Background color of the search text field.
*/
public var backgroundColor: UIColor = UIColor.white.withAlphaComponent(0.3)

/**
A mode that controls when the standard Clear button appears in the text field.
*/
public var clearButtonMode: UITextField.ViewMode = .whileEditing
}
}

/**
Search bar at the top of the NavigationView.

Source: [http://blog.eppz.eu/swiftui-search-bar-in-the-navigation-bar/]( http://blog.eppz.eu/swiftui-search-bar-in-the-navigation-bar/).

MIT License
*/
class SearchBarConfigurator: NSObject, ObservableObject {

let objectWillChange = PassthroughSubject<Void, Never>()

/// The text inside the search bar.
@Published var searchText: String = "" {
willSet {
self.objectWillChange.send()
}
}

/// Instance of the search controller.
let searchController: UISearchController = UISearchController(searchResultsController: nil)

override init() {
super.init()

/// Prevent a gray overlay over the list.
self.searchController.obscuresBackgroundDuringPresentation = false

/// Set the delegate.
self.searchController.searchResultsUpdater = self
}
}

/**
Listen for changes in the search bar's text.
*/
extension SearchBarConfigurator: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {

/// Publish search bar text changes.
if let searchBarText = searchController.searchBar.text {
self.searchText = searchBarText
}
}
}
13 changes: 13 additions & 0 deletions Sources/SupportDocs/SupportOptions/SupportOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SwiftUI
# Parameters
- `categories`: Allows you to group documents with the same `tag` into the same section of the list. Each category may contain more than one `tag`.
- `navigationBar`: Customize the Navigation Bar's `title`, `titleColor`, `dismissButtonTitle`, `buttonTintColor`, and `backgroundColor`.
- `searchBar`: Customize the `placeholder`, `placeholderColor`, `textColor`, `tintColor`, and `backgroundColor` of the Search Bar.
- `progressBar`: Customize the `foregroundColor` and `backgroundColor` of the progress bar.
- `listStyle`: The style of the `List`. Defaults to `.insetGroupedListStyle`.
- `navigationViewStyle`: The style of the `NavigationView`. Defaults to `.defaultNavigationViewStyle`.
Expand All @@ -22,6 +23,8 @@ public struct SupportOptions {

/**
Allows you to group documents with the same `tag` into the same section of the list. Each category may contain more than one `tag`.

Leave as `nil` to display all documents regardless of their `tag`s.
*/
public var categories: [Category]? = nil

Expand All @@ -32,6 +35,13 @@ public struct SupportOptions {
*/
public var navigationBar: NavigationBar = NavigationBar(dismissButtonView: nil)

/**
Customize the appearance of the Search Bar.

Set to `nil` to not show a search bar.
*/
public var searchBar: SearchBar? = SearchBar()

/**
Customize the `foregroundColor` and `backgroundColor` of the progress bar.
*/
Expand All @@ -57,6 +67,7 @@ public struct SupportOptions {

- parameter categories: Allows you to group documents with the same `tag` into the same section of the list. Each category may contain more than one `tag`.
- parameter navigationBar: Customize the Navigation Bar's `title`, `titleColor`, `dismissButtonTitle`, `buttonTintColor`, and `backgroundColor`.
- parameter searchBar: Customize the `placeholder`, `placeholderColor`, `textColor`, `tintColor`, `backgroundColor`, and `clearButtonMode` of the Search Bar.
- parameter progressBar: Customize the `foregroundColor` and `backgroundColor` of the progress bar.
- parameter listStyle: The style of the `List`. Defaults to `.insetGroupedListStyle`.
- parameter navigationViewStyle: The style of the `NavigationView`. Defaults to `.defaultNavigationViewStyle`.
Expand All @@ -65,13 +76,15 @@ public struct SupportOptions {
public init(
categories: [Category]? = nil,
navigationBar: NavigationBar = NavigationBar(dismissButtonView: nil),
searchBar: SearchBar? = SearchBar(),
progressBar: ProgressBar = ProgressBar(),
listStyle: CustomListStyle = CustomListStyle.insetGroupedListStyle,
navigationViewStyle: CustomNavigationViewStyle = CustomNavigationViewStyle.defaultNavigationViewStyle,
other: Other = Other()
) {
self.categories = categories
self.navigationBar = navigationBar
self.searchBar = searchBar
self.progressBar = progressBar
self.listStyle = listStyle
self.navigationViewStyle = navigationViewStyle
Expand Down
Loading

0 comments on commit c58f17a

Please sign in to comment.