Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #69 from Babylonpartners/search-bar-component
Added search bar component
- Loading branch information
Showing
11 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
BentoKit/BentoKit/Components.playground/Pages/Search.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import UIKit | ||
import Bento | ||
import BentoKit | ||
import BentoKitPlaygroundSupport | ||
import PlaygroundSupport | ||
import StyleSheets | ||
|
||
let bundle = Bundle(for: Component.TextInput.self) | ||
let styleSheet = Component.Search.StyleSheet() | ||
.compose(\.searchBar.textInputBackgroundColor, UIColor.gray.withAlphaComponent(0.25)) | ||
.compose(\.searchBar.showsCancelButton, true) | ||
let component = Component.Search( | ||
placeholder: "Placeholder", | ||
keyboardType: .default, | ||
didBeginEditing: { _ in | ||
print("didBeginEditing") | ||
}, | ||
textDidChange: { _, text in | ||
print("textDidChange", text) | ||
}, | ||
cancelButtonClicked: { | ||
print("cancelButtonClicked") | ||
$0.endEditing(true) | ||
}, | ||
styleSheet: styleSheet | ||
) | ||
|
||
PlaygroundPage.current.liveView = renderInTableView(component: component) |
6 changes: 6 additions & 0 deletions
6
BentoKit/BentoKit/Components.playground/Pages/Search.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import Bento | ||
import StyleSheets | ||
|
||
extension Component { | ||
public final class Search: AutoRenderable { | ||
public let configurator: (View) -> Void | ||
public let styleSheet: StyleSheet | ||
|
||
public init( | ||
placeholder: String? = nil, | ||
keyboardType: UIKeyboardType = .default, | ||
didBeginEditing: Optional<(UISearchBar) -> Void> = nil, | ||
textDidChange: Optional<(UISearchBar, String) -> Void> = nil, | ||
cancelButtonClicked: Optional<(UISearchBar) -> Void> = nil, | ||
styleSheet: StyleSheet = StyleSheet() | ||
) { | ||
self.configurator = { view in | ||
view.searchBar.placeholder = placeholder | ||
view.searchBar.keyboardType = keyboardType | ||
view.didBeginEditing = didBeginEditing | ||
view.textDidChange = textDidChange | ||
view.cancelButtonClicked = cancelButtonClicked | ||
view.searchBar.height(styleSheet.searchBar.height) | ||
} | ||
self.styleSheet = styleSheet | ||
} | ||
} | ||
} | ||
|
||
extension Component.Search { | ||
public final class View: BaseView, UISearchBarDelegate { | ||
|
||
let searchBar = UISearchBar() | ||
|
||
var textDidChange: Optional<(UISearchBar, String) -> Void> = nil | ||
var cancelButtonClicked: Optional<(UISearchBar) -> Void> = nil | ||
var didBeginEditing: Optional<(UISearchBar) -> Void> = nil | ||
|
||
public override init(frame: CGRect) { | ||
super.init(frame: frame) | ||
|
||
searchBar.add(to: self) | ||
.pinEdges(to: layoutMarginsGuide) | ||
|
||
searchBar.delegate = self | ||
} | ||
|
||
@available(*, unavailable) | ||
public required init?(coder aDecoder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
public func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { | ||
self.didBeginEditing?(searchBar) | ||
} | ||
|
||
public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { | ||
searchBar.endEditing(true) | ||
} | ||
|
||
public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { | ||
self.textDidChange?(searchBar, searchText) | ||
} | ||
|
||
public func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { | ||
self.cancelButtonClicked?(searchBar) | ||
} | ||
} | ||
} | ||
|
||
extension Component.Search { | ||
public final class StyleSheet: BaseViewStyleSheet<View> { | ||
public let searchBar = SearchBarStyleSheet() | ||
|
||
public init() {} | ||
|
||
public override func apply(to element: View) { | ||
super.apply(to: element) | ||
searchBar.apply(to: element.searchBar) | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
BentoKit/BentoKitTests/SnapshotTests/Components/SearchSnapshotTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import BentoKit | ||
import StyleSheets | ||
import UIKit | ||
@testable import BentoKitPlaygroundSupport | ||
|
||
final class SearchSnapshotTests: SnapshotTestCase { | ||
let placeholder = "Search for address or a postcode" | ||
|
||
override func setUp() { | ||
super.setUp() | ||
self.recordMode = false | ||
} | ||
|
||
func testSearch() { | ||
let styleSheet = Component.Search.StyleSheet() | ||
.compose(\.searchBar.textInputBackgroundColor, UIColor.gray.withAlphaComponent(0.25)) | ||
.compose(\.searchBar.showsCancelButton, true) | ||
|
||
let component = Component.Search(placeholder: placeholder, styleSheet: styleSheet) | ||
|
||
verifyComponentForAllSizes(component: component) | ||
} | ||
|
||
} |
3 changes: 3 additions & 0 deletions
3
.../ReferenceImages_64/BentoKitTests.SearchSnapshotTests/testSearch_iPhone6@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
...erenceImages_64/BentoKitTests.SearchSnapshotTests/testSearch_iPhone6Plus@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
.../ReferenceImages_64/BentoKitTests.SearchSnapshotTests/testSearch_iPhoneX@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import UIKit | ||
|
||
open class SearchBarStyleSheet: ViewStyleSheet<UISearchBar> { | ||
public var textInputBackgroundColor: UIColor = .white | ||
public var textInputCornerRaidus: CGFloat = 10 | ||
public var height: CGFloat = 36 | ||
public var showsCancelButton: Bool = false | ||
public var searchTextPositionAdjustment: UIOffset = UIOffset(horizontal: 8, vertical: 0) | ||
public var keyboardType: UIKeyboardType = .default | ||
public var returnKeyType: UIReturnKeyType = .search | ||
public var enablesReturnKeyAutomatically: Bool = true | ||
|
||
open override func apply(to element: UISearchBar) { | ||
super.apply(to: element) | ||
element.setTextInputBackgroundColor(color: textInputBackgroundColor, | ||
height: height, | ||
cornerRadius: textInputCornerRaidus) | ||
element.showsCancelButton = showsCancelButton | ||
element.searchTextPositionAdjustment = searchTextPositionAdjustment | ||
element.keyboardType = keyboardType | ||
element.returnKeyType = returnKeyType | ||
element.enablesReturnKeyAutomatically = enablesReturnKeyAutomatically | ||
element.barTintColor = tintColor | ||
// remove system background | ||
element.backgroundImage = UIImage() | ||
} | ||
|
||
} | ||
|
||
extension UISearchBar { | ||
func setTextInputBackgroundColor(color: UIColor, height: CGFloat, cornerRadius: CGFloat) { | ||
// creates an image with rounded corners from background color | ||
let size = CGSize(width: cornerRadius * 2, height: height) | ||
let backgroundImage = UIGraphicsImageRenderer(size: size) | ||
.image { imageContext in | ||
let path = UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: cornerRadius) | ||
|
||
imageContext.cgContext.beginPath() | ||
imageContext.cgContext.addPath(path.cgPath) | ||
imageContext.cgContext.closePath() | ||
imageContext.cgContext.clip() | ||
|
||
imageContext.cgContext.setFillColor(color.cgColor) | ||
imageContext.cgContext.fill(CGRect(origin: .zero, size: size)) | ||
} | ||
setSearchFieldBackgroundImage(backgroundImage, for: .normal) | ||
} | ||
} |