Commit 787a893d by Daniel Dahan

initial commit for SearchBarView

parent a13df0f4
......@@ -29,7 +29,7 @@
*/
/*
The following is an example of MaterialSwitch.
The following are examples of MaterialSwitch.
*/
import UIKit
......@@ -40,12 +40,12 @@ class ViewController: UIViewController, MaterialSwitchDelegate {
private var materialSwitch: MaterialSwitch!
/// Reference for NavigationBarView.
private var navigationBarView: NavigationBarView = NavigationBarView()
private var searchBarView: SearchBarView = SearchBarView()
override func viewDidLoad() {
super.viewDidLoad()
prepareView()
prepareNavigationBarView()
prepareSearchBarView()
prepareSmallMaterialSwitch()
prepareNormalMaterialSwitch()
prepareLargeMaterialSwitch()
......@@ -61,11 +61,13 @@ class ViewController: UIViewController, MaterialSwitchDelegate {
}
/// Prepare navigationBarView.
private func prepareNavigationBarView() {
navigationBarView.statusBarStyle = .LightContent
navigationBarView.backgroundColor = MaterialColor.blue.base
view.addSubview(navigationBarView)
private func prepareSearchBarView() {
searchBarView.statusBarStyle = .LightContent
searchBarView.backgroundColor = MaterialColor.blue.base
searchBarView.textField.attributedPlaceholder = NSAttributedString(string:"Search", attributes: [NSForegroundColorAttributeName: MaterialColor.white])
searchBarView.textField.clearButtonMode = .WhileEditing
searchBarView.textField.tintColor = MaterialColor.white
view.addSubview(searchBarView)
}
/// Prepares the Small MaterialSwitch.
......@@ -74,11 +76,15 @@ class ViewController: UIViewController, MaterialSwitchDelegate {
materialSwitch.delegate = self
let image: UIImage? = UIImage(named: "ic_alarm_white")
let alarmButton: FlatButton = FlatButton()
alarmButton.setImage(image, forState: .Normal)
alarmButton.setImage(image, forState: .Highlighted)
let button: FlatButton = FlatButton()
button.setImage(image, forState: .Normal)
button.setImage(image, forState: .Highlighted)
materialSwitch.backgroundColor = MaterialColor.green.base
navigationBarView.leftControls = [materialSwitch, button]
button.setTitle("Back Button", forState: .Normal)
searchBarView.leftControls = [materialSwitch]
searchBarView.rightControls = [alarmButton]
}
/// Prepares the Normal MaterialSwitch.
......@@ -89,6 +95,9 @@ class ViewController: UIViewController, MaterialSwitchDelegate {
materialSwitch.delegate = self
materialSwitch.backgroundColor = MaterialColor.green.base
view.addSubview(materialSwitch)
materialSwitch.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.size(view, child: materialSwitch, width: materialSwitch.width + 100, height: materialSwitch.height + 100)
MaterialLayout.alignFromBottomRight(view, child: materialSwitch, bottom: 16, right: 16)
}
/// Prepares the Large MaterialSwitch.
......
......@@ -40,6 +40,7 @@
96A71EBA1C6FCFA300C0C4AE /* Menu.swift in Headers */ = {isa = PBXBuildFile; fileRef = 65FDC2EA1C66858A00103AC2 /* Menu.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96A71EBB1C6FCFA300C0C4AE /* MenuView.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96A71E901C6FBC2200C0C4AE /* MenuView.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96A71EC71C6FFF0500C0C4AE /* MaterialSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71EC61C6FFF0500C0C4AE /* MaterialSwitch.swift */; };
96A71EF61C71127100C0C4AE /* SearchBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96A71EF51C71127100C0C4AE /* SearchBarView.swift */; };
96D88C1E1C1328D800B91418 /* CaptureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D88BF51C1328D800B91418 /* CaptureView.swift */; };
96D88C1F1C1328D800B91418 /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D88BF61C1328D800B91418 /* CardView.swift */; };
96D88C201C1328D800B91418 /* CapturePreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D88BF71C1328D800B91418 /* CapturePreviewView.swift */; };
......@@ -139,6 +140,7 @@
966F57B71C226D75009185B7 /* TextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
96A71E901C6FBC2200C0C4AE /* MenuView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = "<group>"; };
96A71EC61C6FFF0500C0C4AE /* MaterialSwitch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialSwitch.swift; sourceTree = "<group>"; };
96A71EF51C71127100C0C4AE /* SearchBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBarView.swift; sourceTree = "<group>"; };
96D88BF51C1328D800B91418 /* CaptureView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaptureView.swift; sourceTree = "<group>"; };
96D88BF61C1328D800B91418 /* CardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = "<group>"; };
96D88BF71C1328D800B91418 /* CapturePreviewView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CapturePreviewView.swift; sourceTree = "<group>"; };
......@@ -269,6 +271,14 @@
name = Switch;
sourceTree = "<group>";
};
96A71EF71C71134200C0C4AE /* Search */ = {
isa = PBXGroup;
children = (
96A71EF51C71127100C0C4AE /* SearchBarView.swift */,
);
name = Search;
sourceTree = "<group>";
};
96D88BF41C1328D800B91418 /* Sources */ = {
isa = PBXGroup;
children = (
......@@ -293,6 +303,7 @@
965C58BD1C6B8D3300CFB4E1 /* Grid */,
96A71E921C6FBC2900C0C4AE /* Menu */,
96A71EC51C6FFEF300C0C4AE /* Switch */,
96A71EF71C71134200C0C4AE /* Search */,
);
path = Sources;
sourceTree = "<group>";
......@@ -603,6 +614,7 @@
960B23481C38480E00E96216 /* TextView.swift in Sources */,
96D88C291C1328D800B91418 /* MaterialBasicAnimation.swift in Sources */,
96D88C3A1C1328D800B91418 /* MaterialTextLayer.swift in Sources */,
96A71EF61C71127100C0C4AE /* SearchBarView.swift in Sources */,
96D88C371C1328D800B91418 /* MaterialRadius.swift in Sources */,
960B232F1C383EAA00E96216 /* Material+UIImage+Crop.swift in Sources */,
96D88C241C1328D800B91418 /* ImageCardView.swift in Sources */,
......
......@@ -216,24 +216,13 @@ public class MaterialSwitch: UIControl {
public override var frame: CGRect {
didSet {
var w: CGFloat = 0
switch switchSize {
case .Small:
w = 30
case .Normal:
w = 40
case .Large:
w = 50
layoutSwitch()
}
}
let px: CGFloat = (width - w) / 2
track.frame = CGRectMake(px, (height - trackThickness) / 2, w, trackThickness)
track.cornerRadius = min(track.height, track.width) / 2
button.frame = CGRectMake(px, (height - buttonDiameter) / 2, buttonDiameter, buttonDiameter)
onPosition = width - px - buttonDiameter
offPosition = px
public override var bounds: CGRect {
didSet {
layoutSwitch()
}
}
......@@ -458,4 +447,26 @@ public class MaterialSwitch: UIControl {
track.backgroundColor = trackOffDisabledColor
}
}
/// Laout the button and track views.
private func layoutSwitch() {
var w: CGFloat = 0
switch switchSize {
case .Small:
w = 30
case .Normal:
w = 40
case .Large:
w = 50
}
let px: CGFloat = (width - w) / 2
track.frame = CGRectMake(px, (height - trackThickness) / 2, w, trackThickness)
track.cornerRadius = min(track.height, track.width) / 2
button.frame = CGRectMake(px, (height - buttonDiameter) / 2, buttonDiameter, buttonDiameter)
onPosition = width - px - buttonDiameter
offPosition = px
}
}
......@@ -52,7 +52,25 @@ public class NavigationBarView : MaterialView {
/**
:name: contentInset
*/
public var contentInset: UIEdgeInsets = UIEdgeInsets(top: 24, left: 8, bottom: 8, right: 8) {
public var contentInset: UIEdgeInsets = MaterialEdgeInsetToValue(.Square2) {
didSet {
reloadView()
}
}
/**
:name: titleLabelInsets
*/
public var titleLabelInsetPreset: MaterialEdgeInset = .None {
didSet {
titleLabelInset = MaterialEdgeInsetToValue(titleLabelInsetPreset)
}
}
/**
:name: titleLabelInset
*/
public var titleLabelInset: UIEdgeInsets = UIEdgeInsets(top: 12, left: 0, bottom: 0, right: 0) {
didSet {
reloadView()
}
......@@ -69,6 +87,24 @@ public class NavigationBarView : MaterialView {
}
/**
:name: detailLabelInsets
*/
public var detailLabelInsetPreset: MaterialEdgeInset = .None {
didSet {
detailLabelInset = MaterialEdgeInsetToValue(detailLabelInsetPreset)
}
}
/**
:name: detailLabelInset
*/
public var detailLabelInset: UIEdgeInsets = MaterialEdgeInsetToValue(.None) {
didSet {
reloadView()
}
}
/**
:name: detailLabel
*/
public var detailLabel: UILabel? {
......@@ -79,27 +115,63 @@ public class NavigationBarView : MaterialView {
}
/**
:name: leftControls
:name: leftButtonsInsets
*/
public var leftButtonsInsetPreset: MaterialEdgeInset = .None {
didSet {
leftButtonsInset = MaterialEdgeInsetToValue(leftButtonsInsetPreset)
}
}
/**
:name: leftButtonsInset
*/
public var leftButtonsInset: UIEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0) {
didSet {
reloadView()
}
}
/**
:name: leftButtons
*/
public var leftButtons: Array<UIButton>? {
didSet {
if let v = leftButtons {
for b in v {
b.translatesAutoresizingMaskIntoConstraints = false
}
}
reloadView()
}
}
/**
:name: rightButtonsInsets
*/
public var leftControls: Array<UIControl>? {
public var rightButtonsInsetPreset: MaterialEdgeInset = .None {
didSet {
if let v = leftControls {
for c in v {
// c.translatesAutoresizingMaskIntoConstraints = false
rightButtonsInset = MaterialEdgeInsetToValue(rightButtonsInsetPreset)
}
}
/**
:name: rightButtonsInset
*/
public var rightButtonsInset: UIEdgeInsets = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0) {
didSet {
reloadView()
}
}
/**
:name: rightControls
:name: rightButtons
*/
public var rightControls: Array<UIControl>? {
public var rightButtons: Array<UIButton>? {
didSet {
if let v: Array<UIControl> = rightControls {
for c in v {
c.translatesAutoresizingMaskIntoConstraints = false
if let v = rightButtons {
for b in v {
b.translatesAutoresizingMaskIntoConstraints = false
}
}
reloadView()
......@@ -130,9 +202,9 @@ public class NavigationBarView : MaterialView {
/**
:name: init
*/
public convenience init?(titleLabel: UILabel? = nil, detailLabel: UILabel? = nil, leftControls: Array<UIControl>? = nil, rightControls: Array<UIControl>? = nil) {
public convenience init?(titleLabel: UILabel? = nil, detailLabel: UILabel? = nil, leftButtons: Array<UIButton>? = nil, rightButtons: Array<UIButton>? = nil) {
self.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 70))
prepareProperties(titleLabel, detailLabel: detailLabel, leftControls: leftControls, rightControls: rightControls)
prepareProperties(titleLabel, detailLabel: detailLabel, leftButtons: leftButtons, rightButtons: rightButtons)
}
/**
......@@ -145,49 +217,114 @@ public class NavigationBarView : MaterialView {
v.removeFromSuperview()
}
var verticalFormat: String = "V:|"
var views: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
var metrics: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
var views: Dictionary<String, UIView> = Dictionary<String, UIView>()
var h: String = "H:|"
if nil != titleLabel {
verticalFormat += "-(insetTop)"
metrics["insetTop"] = contentInset.top + titleLabelInset.top
} else if nil != detailLabel {
verticalFormat += "-(insetTop)"
metrics["insetTop"] = contentInset.top + detailLabelInset.top
}
// title
if let v = titleLabel {
verticalFormat += "-[titleLabel]"
views["titleLabel"] = v
addSubview(v)
MaterialLayout.alignToParentHorizontally(self, child: v, left: contentInset.left + titleLabelInset.left, right: contentInset.right + titleLabelInset.right)
}
// detail
if let v = detailLabel {
if nil != titleLabel {
verticalFormat += "-(insetB)"
metrics["insetB"] = titleLabelInset.bottom + detailLabelInset.top
}
verticalFormat += "-[detailLabel]"
views["detailLabel"] = v
addSubview(v)
MaterialLayout.alignToParentHorizontally(self, child: v, left: contentInset.left + detailLabelInset.left, right: contentInset.right + detailLabelInset.right)
}
// leftControls
if let v: Array<UIControl> = leftControls {
// leftButtons
if let v = leftButtons {
if 0 < v.count {
var h: String = "H:|"
var d: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
var i: Int = 0
for c in v {
let k: String = "c\(i)"
for b in v {
let k: String = "b\(i)"
views[k] = c
d[k] = b
if 0 == i++ {
h += "-(left)-"
} else {
h += "-(spacing)-"
h += "-(left_right)-"
}
h += "[\(k)]"
addSubview(c)
c.grid.columns = 1
addSubview(b)
MaterialLayout.alignFromBottom(self, child: b, bottom: contentInset.bottom + leftButtonsInset.bottom)
}
// if 0 < c.bounds.width {
// MaterialLayout.size(self, child: c, width: c.bounds.width, height: c.bounds.height)
// }
if let btn: UIButton = c as? UIButton {
btn.contentEdgeInsets = UIEdgeInsetsZero
addConstraints(MaterialLayout.constraint(h, options: [], metrics: ["left" : contentInset.left + leftButtonsInset.left, "left_right" : leftButtonsInset.left + leftButtonsInset.right], views: d))
}
// MaterialLayout.alignToParentVertically(self, child: c, top: contentInset.top, bottom: contentInset.bottom)
}
// rightButtons
if let v = rightButtons {
if 0 < v.count {
var h: String = "H:"
var d: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
var i: Int = v.count - 1
for b in v {
let k: String = "b\(i)"
d[k] = b
h += "[\(k)]"
if 0 == i-- {
h += "-(right)-"
} else {
h += "-(right_left)-"
}
addSubview(b)
MaterialLayout.alignFromBottom(self, child: b, bottom: contentInset.bottom + rightButtonsInset.bottom)
}
grid.contentInset.top = 20
grid.contentInset.bottom = 10
grid.columns = 10
grid.views = leftControls
addConstraints(MaterialLayout.constraint(h + "|", options: [], metrics: ["right" : contentInset.right + rightButtonsInset.right, "right_left" : rightButtonsInset.right + rightButtonsInset.left], views: d))
}
}
if nil != detailLabel {
if nil == metrics["insetC"] {
metrics["insetBottom"] = contentInset.bottom + detailLabelInset.bottom
} else {
metrics["insetC"] = (metrics["insetC"] as! CGFloat) + detailLabelInset.bottom
}
} else if nil != titleLabel {
if nil == metrics["insetC"] {
metrics["insetBottom"] = contentInset.bottom + titleLabelInset.bottom
} else {
metrics["insetC"] = (metrics["insetC"] as! CGFloat) + titleLabelInset.bottom
}
}
// addConstraints(MaterialLayout.constraint(h + "|", options: [], metrics: ["left" : contentInset.left, "spacing" : 8], views: views))
if 0 < views.count {
verticalFormat += "-(insetBottom)-|"
addConstraints(MaterialLayout.constraint(verticalFormat, options: [], metrics: metrics, views: views))
}
}
/**
......@@ -201,10 +338,10 @@ public class NavigationBarView : MaterialView {
/**
:name: prepareProperties
*/
internal func prepareProperties(titleLabel: UILabel?, detailLabel: UILabel?, leftControls: Array<UIControl>?, rightControls: Array<UIControl>?) {
internal func prepareProperties(titleLabel: UILabel?, detailLabel: UILabel?, leftButtons: Array<UIButton>?, rightButtons: Array<UIButton>?) {
self.titleLabel = titleLabel
self.detailLabel = detailLabel
self.leftControls = leftControls
self.rightControls = rightControls
self.leftButtons = leftButtons
self.rightButtons = rightButtons
}
}
/*
* Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.io>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Material nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
public class SearchBarView : MaterialView {
/**
:name: statusBarStyle
*/
public var statusBarStyle: UIStatusBarStyle = UIApplication.sharedApplication().statusBarStyle {
didSet {
UIApplication.sharedApplication().statusBarStyle = statusBarStyle
}
}
/// Wrapper around grid.contentInset.
public var contentInset: UIEdgeInsets = UIEdgeInsetsZero {
didSet {
grid.contentInset = contentInset
}
}
/// Wrapper around grid.spacing.
public var spacing: CGFloat = 0 {
didSet {
grid.spacing = spacing
}
}
/// SearchBar textField.
public private(set) lazy var textField: TextField = TextField()
/**
:name: leftControls
*/
public var leftControls: Array<UIControl>? {
didSet {
reloadView()
}
}
/**
:name: rightControls
*/
public var rightControls: Array<UIControl>? {
didSet {
reloadView()
}
}
/**
:name: init
*/
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
/**
:name: init
*/
public override init(frame: CGRect) {
super.init(frame: frame)
}
/**
:name: init
*/
public convenience init() {
self.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 70))
}
/**
:name: init
*/
public convenience init?(leftControls: Array<UIControl>? = nil, rightControls: Array<UIControl>? = nil) {
self.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 70))
prepareProperties(leftControls, rightControls: rightControls)
}
public override func didMoveToSuperview() {
super.didMoveToSuperview()
reloadView()
}
/**
:name: reloadView
*/
public func reloadView() {
// clear constraints so new ones do not conflict
removeConstraints(constraints)
for v in subviews {
v.removeFromSuperview()
}
grid.views = []
textField.grid.columns = grid.columns
// leftControls
if let v: Array<UIControl> = leftControls {
if 0 < v.count {
// Size of single grid column.
let g: CGFloat = width / CGFloat(grid.columns)
for c in v {
var w: CGFloat = c.frame.width
if 0 == w {
if let b: UIButton = c as? UIButton {
b.contentEdgeInsets = UIEdgeInsetsZero
}
w = c.intrinsicContentSize().width
}
c.grid.columns = Int(ceil(w / g))
textField.grid.columns -= c.grid.columns
addSubview(c)
grid.views?.append(c)
}
}
}
addSubview(textField)
grid.views?.append(textField)
// rightControls
if let v: Array<UIControl> = rightControls {
if 0 < v.count {
// Size of single grid column.
let g: CGFloat = width / CGFloat(grid.columns)
for c in v {
var w: CGFloat = c.frame.width
if 0 == w {
if let b: UIButton = c as? UIButton {
b.contentEdgeInsets = UIEdgeInsetsZero
}
w = c.intrinsicContentSize().width
}
c.grid.columns = Int(ceil(w / g))
textField.grid.columns -= c.grid.columns
addSubview(c)
grid.views?.append(c)
}
}
}
grid.reloadLayout()
}
/**
:name: prepareView
*/
public override func prepareView() {
super.prepareView()
grid.columns = 10
grid.spacing = 8
grid.contentInset.top = 28
grid.contentInset.left = 8
grid.contentInset.bottom = 8
grid.contentInset.right = 8
depth = .Depth1
prepareTextField()
}
/**
:name: prepareProperties
*/
private func prepareProperties(leftControls: Array<UIControl>?, rightControls: Array<UIControl>?) {
self.leftControls = leftControls
self.rightControls = rightControls
}
private func prepareTextField() {
textField.backgroundColor = MaterialColor.clear
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment