Commit 511b51ba by Daniel Dahan

updated TextView to handle set text with titleLabel

parent d230c6b3
......@@ -3,79 +3,79 @@
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-29@2x-1.png",
"filename" : "MaterialKit-Icon-29@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-29@3x.png",
"filename" : "MaterialKit-Icon-29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-40@2x.png",
"filename" : "MaterialKit-Icon-40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-40@3x.png",
"filename" : "MaterialKit-Icon-40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-60@2x.png",
"filename" : "MaterialKit-Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-60@3x.png",
"filename" : "MaterialKit-Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-29.png",
"filename" : "MaterialKit-Icon-29.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-29@2x.png",
"filename" : "MaterialKit-Icon-29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-40.png",
"filename" : "MaterialKit-Icon-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-40@2x-1.png",
"filename" : "MaterialKit-Icon-40@2x-1.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-76.png",
"filename" : "MaterialKit-Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-76@2x.png",
"filename" : "MaterialKit-Icon-76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-83.5@2x.png",
"filename" : "MaterialKit-Icon-83.5@2x.png",
"scale" : "2x"
}
],
......
......@@ -11,8 +11,6 @@
961F5F2C1C1726A300C94B43 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961F5F2B1C1726A300C94B43 /* ViewController.swift */; };
961F5F311C1726A300C94B43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 961F5F301C1726A300C94B43 /* Assets.xcassets */; };
961F5F341C1726A300C94B43 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 961F5F321C1726A300C94B43 /* LaunchScreen.storyboard */; };
96607D8B1C3F5795008D47D8 /* MaterialKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96607D8A1C3F5795008D47D8 /* MaterialKit.framework */; };
96607D8C1C3F5795008D47D8 /* MaterialKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 96607D8A1C3F5795008D47D8 /* MaterialKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
......@@ -22,7 +20,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
96607D8C1C3F5795008D47D8 /* MaterialKit.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -36,7 +33,6 @@
961F5F301C1726A300C94B43 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
961F5F331C1726A300C94B43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
961F5F351C1726A300C94B43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
96607D8A1C3F5795008D47D8 /* MaterialKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = MaterialKit.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/MaterialKit-gdulktuccbcfwbdfadtpxkworhyc/Build/Products/Debug-iphoneos/MaterialKit.framework"; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -44,7 +40,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
96607D8B1C3F5795008D47D8 /* MaterialKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -54,7 +49,6 @@
961F5F1D1C1726A300C94B43 = {
isa = PBXGroup;
children = (
96607D8A1C3F5795008D47D8 /* MaterialKit.framework */,
961F5F281C1726A300C94B43 /* MaterialLayout */,
961F5F271C1726A300C94B43 /* Products */,
);
......
......@@ -3,79 +3,79 @@
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-29@2x-1.png",
"filename" : "MaterialKit-Icon-29@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-29@3x.png",
"filename" : "MaterialKit-Icon-29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-40@2x.png",
"filename" : "MaterialKit-Icon-40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-40@3x.png",
"filename" : "MaterialKit-Icon-40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-60@2x.png",
"filename" : "MaterialKit-Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "MaterialKit_Icons_Set_Icon-60@3x.png",
"filename" : "MaterialKit-Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-29.png",
"filename" : "MaterialKit-Icon-29.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-29@2x.png",
"filename" : "MaterialKit-Icon-29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-40.png",
"filename" : "MaterialKit-Icon-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-40@2x-1.png",
"filename" : "MaterialKit-Icon-40@2x-1.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-76.png",
"filename" : "MaterialKit-Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-76@2x.png",
"filename" : "MaterialKit-Icon-76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "MaterialKit_Icons_Set_Icon-83.5@2x.png",
"filename" : "MaterialKit-Icon-83.5@2x.png",
"scale" : "2x"
}
],
......
......@@ -31,8 +31,6 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
......
......@@ -29,7 +29,9 @@
*/
/**
MaterialLayout
MaterialLayout is an excellent tool to ease the use of AutoLayout. The following
examples demonstrate laying out a collection of UILabel objects, both vertically
and horizontally.
*/
import UIKit
......@@ -83,8 +85,10 @@ class ViewController: UIViewController {
// Align the labels horizontally with an equal width.
MaterialLayout.alignToParentHorizontally(view, children: children, left: 30, right: 30, spacing: 30)
// Individually set the labels' vertical alignment.
// If this is left out, the intrinsic value is used for the view.
/*
Individually set the labels' vertical alignment.
If this is left out, the intrinsic value is used for the view.
*/
for v in children {
MaterialLayout.alignToParentVertically(view, child: v, top: 100, bottom: 100)
}
......@@ -131,8 +135,10 @@ class ViewController: UIViewController {
// Align the labels vertically with an equal height.
MaterialLayout.alignToParentVertically(view, children: children, top: 100, bottom: 100, spacing: 100)
// Individually set the labels' horizontal alignment.
// If this is left out, the intrinsic value is used for the view.
/*
Individually set the labels' horizontal alignment.
If this is left out, the intrinsic value is used for the view.
*/
for v in children {
MaterialLayout.alignToParentHorizontally(view, child: v, left: 100, right: 100)
}
......
......@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
96607DE31C42C872008D47D8 /* MaterialKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96607DE21C42C872008D47D8 /* MaterialKit.framework */; };
96607DE41C42C872008D47D8 /* MaterialKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 96607DE21C42C872008D47D8 /* MaterialKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
966F57A11C226BAA009185B7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966F57A01C226BAA009185B7 /* AppDelegate.swift */; };
966F57A31C226BAA009185B7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 966F57A21C226BAA009185B7 /* ViewController.swift */; };
966F57A81C226BAA009185B7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 966F57A71C226BAA009185B7 /* Assets.xcassets */; };
......@@ -20,6 +22,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
96607DE41C42C872008D47D8 /* MaterialKit.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
......@@ -27,6 +30,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
96607DE21C42C872008D47D8 /* MaterialKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = MaterialKit.framework; path = "/Users/danieldahan/Library/Developer/Xcode/DerivedData/MaterialKit-gdulktuccbcfwbdfadtpxkworhyc/Build/Products/Debug-iphoneos/MaterialKit.framework"; sourceTree = "<absolute>"; };
966F579D1C226BAA009185B7 /* TextField.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TextField.app; sourceTree = BUILT_PRODUCTS_DIR; };
966F57A01C226BAA009185B7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
966F57A21C226BAA009185B7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
......@@ -40,6 +44,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
96607DE31C42C872008D47D8 /* MaterialKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -49,6 +54,7 @@
966F57941C226BAA009185B7 = {
isa = PBXGroup;
children = (
96607DE21C42C872008D47D8 /* MaterialKit.framework */,
966F579F1C226BAA009185B7 /* TextField */,
966F579E1C226BAA009185B7 /* Products */,
);
......
......@@ -65,6 +65,7 @@ class ViewController: UIViewController, TextFieldDelegate {
nameField.titleLabelColor = MaterialColor.grey.lighten1
nameField.titleLabelActiveColor = MaterialColor.blue.accent3
nameField.clearButtonMode = .WhileEditing
nameField.text = "Hello"
view.addSubview(nameField)
}
......
......@@ -47,7 +47,7 @@ class ViewController: UIViewController, TextDelegate, TextViewDelegate {
func prepareTextView() {
let layoutManager: NSLayoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: view.bounds.size)
let textContainer: NSTextContainer = NSTextContainer(size: view.bounds.size)
layoutManager.addTextContainer(textContainer)
text.delegate = self
......@@ -55,8 +55,6 @@ class ViewController: UIViewController, TextDelegate, TextViewDelegate {
textView = TextView(textContainer: textContainer)
textView.delegate = self
textView.editable = true
textView.selectable = true
textView.font = RobotoFont.regular
textView.placeholderLabel = UILabel()
......
Pod::Spec.new do |s|
s.name = 'MK'
s.version = '1.27.12'
s.version = '1.27.13'
s.license = 'BSD'
s.summary = 'Beautiful Material Design in Swift.'
s.homepage = 'http://materialkit.io'
......
![GraphKit](http://www.graphkit.io/GK/GraphKit.png)
![MaterialKit](http://www.materialkit.io/MK/MaterialKit.png)
## Welcome to GraphKit
# Welcome to MaterialKit
GraphKit is a data framework. A data framework solves the issue of modeling, mapping, moving, and manipulating data. GraphKit may be used in its simplest form to save and search for data, or it may be used to create robust data-driven applications. What makes GraphKit interesting is in its approach to take the dirty work out of writing algorithms, building recommendations, and driving application behavior.
## Why use GraphKit?
Working with data is complicated and usually left to the end of the application development lifecycle. It takes time to setup models with CoreData and even more time to make changes to that model. To ease the use of data in an application, and to make it more enjoyable, GraphKit removes the complexity and allows developers to focus on the parts they care about.
With GraphKit, it becomes easy to map Entity models, create relationships, and build realtime predictive applications that bring a unique experience to your end user. Data structures within GraphKit have a probability extension that allow search queries to become more than simple dumps of data. All data changes can easily be observed to create a completely reactive experience for users, while easing the development of your application.
MaterialKit is a graphics and animation framework based on Google's Material Design. A major goal in the design of MaterialKit is to allow the creativity of others to easily be expressed. The following README is written to get you started, and is by no means a complete tutorial on all that is possible. Additional examples may be found in the Examples directory that go beyond the README documentation.
## How To Get Started
- [Download GraphKit](https://github.com/CosmicMind/GraphKit/archive/master.zip).
- [Download MaterialKit](https://github.com/CosmicMind/MaterialKit/archive/master.zip).
- Explore the examples in the Examples directory.
## Communication
- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/graphkit). (Tag 'graphkit')
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/graphkit).
- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/materialkit). (Tag 'materialkit')
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/materialkit).
- If you **found a bug**, _and can provide steps to reliably reproduce it_, open an issue.
- If you **have a feature request**, open an issue.
- If you **want to contribute**, submit a pull request.
......@@ -31,16 +25,16 @@ With GraphKit, it becomes easy to map Entity models, create relationships, and b
$ gem install cocoapods
```
> CocoaPods 0.39.0+ is required to build GraphKit 4.0.0+.
> CocoaPods 0.39.0+ is required to build MaterialKit 1.0.0+.
To integrate GraphKit into your Xcode project using CocoaPods, specify it in your `Podfile`:
To integrate MaterialKit into your Xcode project using CocoaPods, specify it in your `Podfile`:
```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'GK', '~> 4.0'
pod 'MK', '~> 1.0'
```
Then, run the following command:
......@@ -59,466 +53,597 @@ You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
```
To integrate GraphKit into your Xcode project using Carthage, specify it in your Cartfile:
To integrate MaterialKit into your Xcode project using Carthage, specify it in your Cartfile:
```bash
github "CosmicMind/GraphKit"
github "CosmicMind/MaterialKit"
```
Run carthage to build the framework and drag the built GraphKit.framework into your Xcode project.
Run carthage to build the framework and drag the built MaterialKit.framework into your Xcode project.
### Changelog
The GraphKit framework is a fast growing project and will encounter changes throughout its development. It is recommended that the [Changelog](https://github.com/CosmicMind/GraphKit/wiki/Changelog) be reviewed prior to updating versions.
The MaterialKit framework is a fast growing project and will encounter changes throughout its development. It is recommended that the [Changelog](https://github.com/CosmicMind/MaterialKit/wiki/Changelog) be reviewed prior to updating versions.
### A Quick Tour
* [Entity](#entity)
* [Bond](#bond)
* [Action](#action)
* [Groups](#groups)
* [Probability](#probability)
* [Data Driven](#datadriven)
* [Faceted Search](#facetedsearch)
* [JSON](#json)
* [Data Structures](#datastructures)
* [DoublyLinkedList](#doublylinkedlist)
* [Stack](#stack)
* [Queue](#queue)
* [Deque](#deque)
* [RedBlackTree](#redblacktree)
* [SortedSet](#sortedset)
* [SortedMultiSet](#sortedmultiset)
* [SortedDictionary](#sorteddictionary)
* [SortedMultiDictionary](#sortedmultidictionary)
* [TextField](#textfield)
* [TextView](#textview)
* [MaterialLayer](#materiallayer)
* [MaterialView](#materialview)
* [MaterialPulseView](#materialpulseview)
* [FlatButton](#flatbutton)
* [RaisedButton](#raisedbutton)
* [FabButton](#fabbutton)
* [CardView](#cardview)
* [ImageCardView](#imagecardview)
* [NavigationBarView](#navigationbarview)
* [SideNavigationViewController](#sidenavigationviewcontroller)
* [CaptureView](#captureview)
* [MaterialColor](#materialcolor)
* [MaterialLayout](#materiallayout)
### Upcoming
* Example Projects
* Additional Data Structures
* SearchBarView
* SearchBarViewController
* TabView
* TabViewController
* Scrolling Techniques
* Dialogs
* Snackbar
* ProgressBar (circular and horizontal)
* DatePicker
* TimePicker
* More Examples
<a name="entity"></a>
### Entity
<a name="textfield"></a>
### TextField
An Entity is a model object that represents a person, place, or thing. For example a User, Button, Photo, Video, or Note -- pretty much anything that you would like to objectify. To distinguish between different Entity types, the _type_ instance property is set upon instantiation of a new Entity object. For Example, creating different Entity types is as easy as the code below.
A TextField is an excellent way to improve UX. Checkout the Examples directory for a project using this component.
```swift
// Create a User Entity type.
let user: Entity = Entity(type: "User")
![MaterialKitTextField](http://www.materialkit.io/MK/MaterialKitTextField.gif)
// Create a Book Entity type.
let book: Entity = Entity(type: "Book")
// Create a Photo Entity type.
let photo: Entity = Entity(type: "Photo")
```swift
let textField: TextField = TextField(frame: CGRectMake(57, 100, 300, 24))
textField.placeholder = "First Name"
textField.font = RobotoFont.regularWithSize(20)
textField.textColor = MaterialColor.black
textField.titleLabel = UILabel()
textField.titleLabel!.font = RobotoFont.mediumWithSize(12)
textField.titleLabelColor = MaterialColor.grey.lighten1
textField.titleLabelActiveColor = MaterialColor.blue.accent3
textField.clearButtonMode = .WhileEditing
view.addSubview(textField)
// Add nameField to UIViewController.
view.addSubview(nameField)
```
When a new Entity is created, a record in CoreData is made, which provides a unique _id_ for the object. The Entity is not yet saved, so discarding an Entity does not create any unnecessary overhead.
<a name="textview"></a>
### TextView
[Learn More About Entity Objects](https://github.com/CosmicMind/GraphKit/wiki/Entity)
Easily match any regular expression pattern in a body of text. Below is an example of the default hashtag pattern matching.
<a name="bond"></a>
### Bond
![MaterialKitTextView](http://www.materialkit.io/MK/MaterialKitTextView.gif)
A Bond is a model object that represents a relationship between two [Entity](https://github.com/CosmicMind/GraphKit/wiki/Entity) objects. To distinguish between different Bond types, the _type_ instance property is set upon instantiation of a new Bond object. To form meaningful relationships, sentence structures are used, with a _subject_ and _object_ that form the relationship. For example, we have two Entity types, a User and a Book. The User is the Author of the Book, so how is this modeled? In a sentence it would be, _User is Author of Book_. The User is the _subject_ in this case, and the _object_ is the Book. In code, the following is how this would be modeled.
Checkout the Examples Programmatic directory for a sample project using this wonderful component.
```swift
// Create a User Entity type.
let user: Entity = Entity(type: "User")
<a name="materiallayer"></a>
### MaterialLayer
// Create a Book Entity type.
let book: Entity = Entity(type: "Book")
MaterialLayer is a lightweight CAShapeLayer used throughout MaterialKit. It is designed to easily take shape, depth, and animations. Below is an example demonstrating the ease of adding shape and depth to MaterialLayer.
// Create an Author Bond type.
let author: Bond = Bond(type: "Author")
// Make the relationship.
author.subject = user
author.object = book
```
Another way to think of this relationship through a sentence structure is, _the Book was Written by the User_. So now the Book is the _subject_, the User is the _object_, and Written is the relationship. In code, our example now looks like the following.
![MaterialKitMaterialLayer](http://www.materialkit.io/MK/MaterialKitMaterialLayer.gif)
```swift
// Create a Written Bond type.
let written: Bond = Bond(type: "Written")
let materialLayer: MaterialLayer = MaterialLayer(frame: CGRectMake(132, 132, 150, 150))
materialLayer.image = UIImage(named: "CosmicMindAppIcon")
materialLayer.shape = .Circle
materialLayer.shadowDepth = .Depth2
// Make the relationship.
written.subject = book
written.object = user
// Add layer to UIViewController.
view.layer.addSublayer(materialLayer)
```
Although both would work.
[Learn More About Bond Objects](https://github.com/CosmicMind/GraphKit/wiki/Bond)
<a name="materialview"></a>
### MaterialView
<a name="action"></a>
### Action
MaterialView is the base UIView class used throughout MaterialKit. Like MaterialLayer, it is designed to easily take shape, depth, and animations. The major difference is that MaterialView has all the added features of the UIView class. Below is an example of setting a MaterialView's cornerRadius, shape, and depth.
An Action is used to form a relationship between many Entity Objects. Like an Entity, an Action also has a type property that specifies the collection to which it belongs to. An Action's relationship structure is like a sentence, in that it relates a collection of Subjects to a collection of Objects. Below is an example of a User purchasing many Books. It may be thought of as "User Purchased these Book(s)."
![MaterialKitMaterialView](http://www.materialkit.io/MK/MaterialKitMaterialView.gif)
```swift
let graph: Graph = Graph()
let user: Entity = Entity(type: "User")
let books: Array<Entity> = graph.searchForEntity(types: ["Book"])
let purchased: Action = Action(type: "Purchased")
purchased.addSubject(user)
for book in books {
purchased.addObject(book)
}
graph.save()
let materialView: MaterialView = MaterialView(frame: CGRectMake(132, 132, 150, 150))
materialView.image = UIImage(named: "FocusAppIcon")
materialView.shape = .Square
materialView.shadowDepth = .Depth2
materialView.cornerRadius = .Radius3
// Add view to UIViewController.
view.addSubview(materialView)
```
<a name="groups"></a>
### Groups
<a name="materialpulseview"></a>
### MaterialPulseView
Groups are used to organize Entities, Bonds, and Actions into different collections from their types. This allows multiple types to exist in a single collection. For example, a Photo and Video Entity type may exist in a group called Media. Another example may be including a Photo and Book Entity type in a Favorites group for your users' account. Below are examples of using groups.
MaterialPulseView is at the heart of all pulse animations. Any view that subclasses MaterialPulseView instantly inherits the pulse animation with full customizability.
```swift
let photo: Entity = Entity(type: "Photo")
photo.addGroup("Media")
photo.addGroup("Favorites")
photo.addGroup("Holiday Album")
let video: Entity = Entity(type: "Video")
video.addGroup("Media")
![MaterialKitMaterialPulseView](http://www.materialkit.io/MK/MaterialKitMaterialPulseView.gif)
let book: Entity = Entity(type: "Book")
book.addGroup("Favorites")
book.addGroup("To Read")
```swift
let materialPulseView: MaterialPulseView = MaterialPulseView(frame: CGRectMake(132, 132, 150, 150))
materialPulseView.image = UIImage(named: "ContentAppIcon")
materialPulseView.shape = .Circle
materialPulseView.shadowDepth = .Depth2
// Searching groups.
let favorites: Array<Entity> = graph.searchForEntity(groups: ["Favorites"])
// Add view to UIViewController.
view.addSubview(materialPulseView)
```
<a name="probability"></a>
### Probability
<a name="flatbutton"></a>
### FlatButton
Probability is a core feature within GraphKit. Your application may be completely catered to your users' habits and usage. To demonstrate this wonderful feature, let's look at some examples:
A FlatButton is the best place to start when introducing MaterialKit buttons. It is simple, clean, and very effective. Below is an example of a FlatButton in action.
Determining the probability of rolling a 3 using a die of 6 numbers.
![MaterialKitFlatButton](http://www.materialkit.io/MK/MaterialKitFlatButton.gif)
```swift
let die: Array<Int> = Array<Int>(arrayLiteral: 1, 2, 3, 4, 5, 6)
print(die.probabilityOf(3)) // Output: 0.166666666666667
```
The expected value of rolling a 3 or 6 with 100 trials using a die of 6 numbers.
let button: FlatButton = FlatButton(frame: CGRectMake(107, 107, 200, 65))
button.setTitle("Flat", forState: .Normal)
button.titleLabel!.font = RobotoFont.mediumWithSize(32)
```swift
let die: Array<Int> = Array<Int>(arrayLiteral: 1, 2, 3, 4, 5, 6)
print(die.expectedValueOf(100, elements: 3, 6)) // Output: 33.3333333333333
// Add to UIViewController.
view.addSubview(button)
```
Recommending a Physics book if the user is likely to buy a Physics book.
<a name="raisedbutton"></a>
### RaisedButton
```swift
let purchased: Array<Action> = graph.searchForAction(types: ["Purchased"])
let pOfX: Double = purchased.probabilityOf { (action: Action) in
if let entity: Entity = action.objects.first {
if "Book" == entity.type {
return entity.hasGroup("Physics")
}
}
return false
}
if 33.33 < pOfX {
// Recommend a Physics book.
}
```
<a name="datadriven"></a>
### Data Driven
A RaisedButton is sure to get attention. Take a look at the following animation example.
As data moves through your application, the state of information may be observed to create a reactive experience. Below is an example of watching when a "User Clicked a Button".
![MaterialKitRaisedButton](http://www.materialkit.io/MK/MaterialKitRaisedButton.gif)
```swift
// Set the UIViewController's Protocol to GraphDelegate.
let graph: Graph = Graph()
graph.delegate = self
graph.watchForAction(types: ["Clicked"])
let user: Entity = Entity(type: "User")
let clicked: Action = Action(type: "Clicked")
let button: Entity = Entity(type: "Button")
clicked.addSubject(user)
clicked.addObject(button)
graph.save()
// Delegate method.
func graphDidInsertAction(graph: Graph, action: Action) {
switch(action.type) {
case "Clicked":
print(action.subjects.first?.type) // User
print(action.objects.first?.type) // Button
case "Swiped":
// Handle swipe.
default:break
}
}
```
<a name="facetedsearch"></a>
### Faceted Search
To explore the intricate relationships within the Graph, the search API adopts a faceted design. This allows the exploration of your data through any view point. The below examples show how to use the Graph search API:
let button: RaisedButton = RaisedButton(frame: CGRectMake(107, 207, 200, 65))
button.setTitle("Raised", forState: .Normal)
button.titleLabel!.font = RobotoFont.mediumWithSize(32)
Searching multiple Entity types.
```swift
let collection: Array<Entity> = graph.searchForEntity(types: ["Photo", "Video"])
// Add to UIViewController.
view.addSubview(button)
```
Searching multiple Entity groups.
<a name="fabbutton"></a>
### FabButton
```swift
let collection: Array<Entity> = graph.searchForEntity(groups: ["Media", "Favorites"])
```
A FabButton is essential to Material Design's overall look. Below showcases its beauty.
Searching multiple Entity properties.
![MaterialKitFabButton](http://www.materialkit.io/MK/MaterialKitFabButton.gif)
```swift
let collection: Array<Entity> = graph.searchForEntity(properties: [(key: "name", value: "Eve"), ("age", 27)])
let img: UIImage? = UIImage(named: "ic_create_white")
let button: FabButton = FabButton(frame: CGRectMake(175, 315, 64, 64))
button.setImage(img, forState: .Normal)
button.setImage(img, forState: .Highlighted)
// Add to UIViewController.
view.addSubview(button)
```
Searching multiple facets simultaneously will aggregate all results into a single collection.
<a name="cardview"></a>
### CardView
```swift
let collection: Array<Entity> = graph.searchForEntity(types: ["Photo", "Friends"], groups: ["Media", "Favorites"])
```
Right out of the box to a fully customizable configuration, CardView always stands out. Take a look at a few examples in action and find more in the Examples directory.
Filters may be used to narrow in on a search result. For example, searching a book title and group within purchases.
![MaterialKitCardView](http://www.materialkit.io/MK/MaterialKitCardView.gif)
```swift
let collection: Array<Action> = graph.searchForAction(types: ["Purchased"]).filter { (action: Action) -> Bool in
if let entity: Entity = action.objects.first {
if "Book" == entity.type && "The Holographic Universe" == entity["title"] as? String {
return entity.hasGroup("Physics")
}
}
return false
}
let cardView: CardView = CardView()
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "Welcome Back!"
titleLabel.textColor = MaterialColor.blue.darken1
titleLabel.font = RobotoFont.mediumWithSize(20)
cardView.titleLabel = titleLabel
// Detail label.
let detailLabel: UILabel = UILabel()
detailLabel.text = "It’s been a while, have you read any new books lately?"
detailLabel.numberOfLines = 0
cardView.detailLabel = detailLabel
// Yes button.
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.blue.lighten1
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setTitle("YES", forState: .Normal)
btn1.setTitleColor(MaterialColor.blue.darken1, forState: .Normal)
// No button.
let btn2: FlatButton = FlatButton()
btn2.pulseColor = MaterialColor.blue.lighten1
btn2.pulseFill = true
btn2.pulseScale = false
btn2.setTitle("NO", forState: .Normal)
btn2.setTitleColor(MaterialColor.blue.darken1, forState: .Normal)
// Add buttons to left side.
cardView.leftButtons = [btn1, btn2]
// To support orientation changes, use MaterialLayout.
view.addSubview(cardView)
cardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: cardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: cardView, left: 20, right: 20)
```
<a name="json"></a>
### JSON
Easily remove the pulse animation and add a background image for an entirely new feel.
JSON is a widely used format for serializing data. GraphKit comes with a JSON toolset. Below are some examples of its usage.
![MaterialKitCardViewFavorite](http://www.materialkit.io/MK/MaterialKitCardViewFavorite.gif)
```swift
// Serialize Dictionary.
let data: NSData? = JSON.serialize(["user": ["username": "daniel", "password": "abc123", "token": 123456789]])
// Parse NSData.
let j1: JSON? = JSON.parse(data!)
print(j1?["user"]?["username"]?.asString) // Output: "daniel"
// Stringify.
let stringified: String? = JSON.stringify(j1!)
print(stringified) // Output: "{\"user\":{\"password\":\"abc123\",\"token\":123456789,\"username\":\"daniel\"}}"
// Parse String.
let j2: JSON? = JSON.parse(stringified!)
print(j2?["user"]?["token"]?.asInt) // Output: 123456789
let cardView: CardView = CardView()
cardView.divider = false
cardView.backgroundColor = MaterialColor.red.darken1
cardView.pulseScale = false
cardView.pulseColor = nil
cardView.image = UIImage(named: "iTunesArtwork")?.resize(toWidth: 400)
cardView.contentsGravity = .BottomRight
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "MaterialKit"
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.mediumWithSize(24)
cardView.titleLabel = titleLabel
// Detail label.
let detailLabel: UILabel = UILabel()
detailLabel.text = "Build beautiful software."
detailLabel.textColor = MaterialColor.white
detailLabel.numberOfLines = 0
cardView.detailLabel = detailLabel
// Favorite button.
let img1: UIImage? = UIImage(named: "ic_favorite_white")
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.white
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setImage(img1, forState: .Normal)
btn1.setImage(img1, forState: .Highlighted)
// Add buttons to left side.
cardView.leftButtons = [btn1]
// To support orientation changes, use MaterialLayout.
view.addSubview(cardView)
cardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: cardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: cardView, left: 20, right: 20)
```
<a name="datastructures"></a>
### Data Structures
Adjust the alignment of the UI elements to create different configurations of the CardView.
GraphKit comes packed with some powerful data structures to help write algorithms. The following structures are included: DoublyLinkedList, Stack, Queue, Deque, RedBlackTree, SortedSet, SortedMultiSet, SortedDictionary, and SortedMultiDictionary.
<a name="doublylinkedlist"></a>
### DoublyLinkedList
The DoublyLinkedList data structure is excellent for large growing collections of data. Below is an example of its usage.
![MaterialKitCardViewDataDriven](http://www.materialkit.io/MK/MaterialKitCardViewDataDriven.gif)
```swift
let listA: DoublyLinkedList<Int> = DoublyLinkedList<Int>()
listA.insertAtFront(3)
listA.insertAtFront(2)
listA.insertAtFront(1)
let listB: DoublyLinkedList<Int> = DoublyLinkedList<Int>()
listB.insertAtBack(4)
listB.insertAtBack(5)
listB.insertAtBack(6)
let listC: DoublyLinkedList<Int> = listA + listB
listC.cursorToFront()
repeat {
print(listC.cursor)
} while nil != listC.next
// Output:
// 1
// 2
// 3
// 4
// 5
// 6
let cardView: CardView = CardView()
cardView.dividerInset.left = 100
cardView.titleLabelInset.left = 100
cardView.detailLabelInset.left = 100
cardView.pulseColor = MaterialColor.teal.lighten4
// Image.
cardView.image = UIImage(named: "GraphKit")
cardView.contentsGravity = .TopLeft
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "GraphKit"
titleLabel.font = RobotoFont.mediumWithSize(24)
cardView.titleLabel = titleLabel
// Detail label.
let detailLabel: UILabel = UILabel()
detailLabel.text = "Build scalable data-driven apps."
detailLabel.numberOfLines = 0
cardView.detailLabel = detailLabel
// LEARN MORE button.
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.teal.lighten1
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setTitle("LEARN MORE", forState: .Normal)
btn1.setTitleColor(MaterialColor.teal.darken1, forState: .Normal)
// Add buttons to right side.
cardView.rightButtons = [btn1]
// To support orientation changes, use MaterialLayout.
view.addSubview(cardView)
cardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: cardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: cardView, left: 20, right: 20)
```
<a name="stack"></a>
### Stack
CardViews are so flexible they create entirely new components by removing all but certain elements. For example, bellow is a button bar by only setting the button values of the CardView.
The Stack data structure is a container of objects that are inserted and removed according to the last-in-first-out (LIFO) principle. Below is an example of its usage.
![MaterialKitCardViewButtonBar](http://www.materialkit.io/MK/MaterialKitCardViewButtonBar.gif)
```swift
let stack: Stack<Int> = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
while !stack.isEmpty {
print(stack.pop())
}
// Output:
// 3
// 2
// 1
let cardView: CardView = CardView()
cardView.divider = false
cardView.pulseColor = nil
cardView.pulseScale = false
cardView.backgroundColor = MaterialColor.blueGrey.darken4
// Favorite button.
let img1: UIImage? = UIImage(named: "ic_search_white")
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.white
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setImage(img1, forState: .Normal)
btn1.setImage(img1, forState: .Highlighted)
// BUTTON 1 button.
let btn2: FlatButton = FlatButton()
btn2.pulseColor = MaterialColor.teal.lighten3
btn2.pulseFill = true
btn2.pulseScale = false
btn2.setTitle("BUTTON 1", forState: .Normal)
btn2.setTitleColor(MaterialColor.teal.lighten3, forState: .Normal)
btn2.titleLabel!.font = RobotoFont.regularWithSize(20)
// BUTTON 2 button.
let btn3: FlatButton = FlatButton()
btn3.pulseColor = MaterialColor.teal.lighten3
btn3.pulseFill = true
btn3.pulseScale = false
btn3.setTitle("BUTTON 2", forState: .Normal)
btn3.setTitleColor(MaterialColor.teal.lighten3, forState: .Normal)
btn3.titleLabel!.font = RobotoFont.regularWithSize(20)
// Add buttons to left side.
cardView.leftButtons = [btn1]
// Add buttons to right side.
cardView.rightButtons = [btn2, btn3]
// To support orientation changes, use MaterialLayout.
view.addSubview(cardView)
cardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: cardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: cardView, left: 20, right: 20)
```
<a name="queue"></a>
### Queue
<a name="imagecardview"></a>
### ImageCardView
Bold and attractive, ImageCardView is the next step from a CardView. In the Examples folder you will find examples using the ImageCardView. Below are some animations to give you an idea of the possibilities the ImageCardView has to offer.
The Queue data structure is a container of objects that are inserted and removed according to the first-in-first-out (FIFO) principle. Below is an example of its usage.
![MaterialKitImageCardView](http://www.materialkit.io/MK/MaterialKitImageCardView.gif)
```swift
let queue: Queue<Int> = Queue<Int>()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
while !queue.isEmpty {
print(queue.dequeue())
}
// Output:
// 1
// 2
// 3
let imageCardView: ImageCardView = ImageCardView()
// Image.
let size: CGSize = CGSizeMake(UIScreen.mainScreen().bounds.width - CGFloat(40), 150)
imageCardView.image = UIImage.imageWithColor(MaterialColor.cyan.darken1, size: size)
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "Welcome Back!"
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.mediumWithSize(24)
imageCardView.titleLabel = titleLabel
imageCardView.titleLabelInset.top = 100
// Detail label.
let detailLabel: UILabel = UILabel()
detailLabel.text = "It’s been a while, have you read any new books lately?"
detailLabel.numberOfLines = 0
imageCardView.detailLabel = detailLabel
// Yes button.
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.cyan.lighten1
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setTitle("YES", forState: .Normal)
btn1.setTitleColor(MaterialColor.cyan.darken1, forState: .Normal)
// No button.
let btn2: FlatButton = FlatButton()
btn2.pulseColor = MaterialColor.cyan.lighten1
btn2.pulseFill = true
btn2.pulseScale = false
btn2.setTitle("NO", forState: .Normal)
btn2.setTitleColor(MaterialColor.cyan.darken1, forState: .Normal)
// Add buttons to left side.
imageCardView.leftButtons = [btn1, btn2]
// To support orientation changes, use MaterialLayout.
view.addSubview(imageCardView)
imageCardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: imageCardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: imageCardView, left: 20, right: 20)
```
<a name="deque"></a>
### Deque
Remove elements, such as details to create a fresh look for your images.
The Deque data structure is a container of objects that are inserted and removed according to the first-in-first-out (FIFO) and last-in-first-out (LIFO) principle. Essentially, a Deque is a Stack and Queue combined. Below are examples of its usage.
![MaterialKitImageCardViewBackgroundImage](http://www.materialkit.io/MK/MaterialKitImageCardViewBackgroundImage.gif)
```swift
let dequeA: Deque<Int> = Deque<Int>()
dequeA.insertAtBack(1)
dequeA.insertAtBack(2)
dequeA.insertAtBack(3)
while !dequeA.isEmpty {
print(dequeA.removeAtFront())
}
// Output:
// 1
// 2
// 3
let dequeB: Deque<Int> = Deque<Int>()
dequeB.insertAtBack(4)
dequeB.insertAtBack(5)
dequeB.insertAtBack(6)
while !dequeB.isEmpty {
print(dequeB.removeAtBack())
}
// Output:
// 6
// 5
// 4
let imageCardView: ImageCardView = ImageCardView()
imageCardView.divider = false
// Image.
imageCardView.image = UIImage(named: "MaterialKitImageCardViewBackgroundImage")
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "Material Design"
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.regularWithSize(24)
imageCardView.titleLabel = titleLabel
imageCardView.titleLabelInset.top = 80
// Star button.
let img1: UIImage? = UIImage(named: "ic_star_grey_darken_2")
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.blueGrey.lighten1
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setImage(img1, forState: .Normal)
btn1.setImage(img1, forState: .Highlighted)
// Favorite button.
let img2: UIImage? = UIImage(named: "ic_favorite_grey_darken_2")
let btn2: FlatButton = FlatButton()
btn2.pulseColor = MaterialColor.blueGrey.lighten1
btn2.pulseFill = true
btn2.pulseScale = false
btn2.setImage(img2, forState: .Normal)
btn2.setImage(img2, forState: .Highlighted)
// Share button.
let img3: UIImage? = UIImage(named: "ic_share_grey_darken_2")
let btn3: FlatButton = FlatButton()
btn3.pulseColor = MaterialColor.blueGrey.lighten1
btn3.pulseFill = true
btn3.pulseScale = false
btn3.setImage(img3, forState: .Normal)
btn3.setImage(img3, forState: .Highlighted)
// Add buttons to right side.
imageCardView.rightButtons = [btn1, btn2, btn3]
// To support orientation changes, use MaterialLayout.
view.addSubview(imageCardView)
imageCardView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: imageCardView, top: 100)
MaterialLayout.alignToParentHorizontally(view, child: imageCardView, left: 20, right: 20)
```
<a name="redblacktree"></a>
### RedBlackTree
<a name="navigationbarview"></a>
### NavigationBarView
A RedBlackTree is a Balanced Binary Search Tree that maintains insert, remove, update, and search operations in a complexity of O(logn). The GraphKit implementation of a RedBlackTree also includes an order-statistic, which allows the data structure to be accessed using subscripts like an array or dictionary. RedBlackTrees may store unique keys or non-unique key values. Below is an example of its usage.
One of Material Design's greatest additions to UI is the NavigationBarView. In the Examples folder, you can checkout some code to get you started with this wonderful component.
![MaterialKitNavigationBarView](http://www.materialkit.io/MK/MaterialKitNavigationBarView.gif)
```swift
let rbA: RedBlackTree<Int, Int> = RedBlackTree<Int, Int>(uniqueKeys: true)
for var i: Int = 1000; 0 < i; --i {
rbA.insert(1, value: 1)
rbA.insert(2, value: 2)
rbA.insert(3, value: 3)
}
print(rbA.count) // Output: 3
let navigationBarView: NavigationBarView = NavigationBarView()
// Stylize.
navigationBarView.backgroundColor = MaterialColor.indigo.darken1
// To lighten the status bar add the "View controller-based status bar appearance = NO"
// to your info.plist file and set the following property.
navigationBarView.statusBarStyle = .LightContent
// Title label.
let titleLabel: UILabel = UILabel()
titleLabel.text = "MaterialKit"
titleLabel.textAlignment = .Left
titleLabel.textColor = MaterialColor.white
titleLabel.font = RobotoFont.regularWithSize(20)
navigationBarView.titleLabel = titleLabel
navigationBarView.titleLabelInset.left = 64
// Detail label.
let detailLabel: UILabel = UILabel()
detailLabel.text = "Build Beautiful Software"
detailLabel.textAlignment = .Left
detailLabel.textColor = MaterialColor.white
detailLabel.font = RobotoFont.regularWithSize(12)
navigationBarView.detailLabel = detailLabel
navigationBarView.detailLabelInset.left = 64
// Menu button.
let img1: UIImage? = UIImage(named: "ic_menu_white")
let btn1: FlatButton = FlatButton()
btn1.pulseColor = MaterialColor.white
btn1.pulseFill = true
btn1.pulseScale = false
btn1.setImage(img1, forState: .Normal)
btn1.setImage(img1, forState: .Highlighted)
// Star button.
let img2: UIImage? = UIImage(named: "ic_star_white")
let btn2: FlatButton = FlatButton()
btn2.pulseColor = MaterialColor.white
btn2.pulseFill = true
btn2.pulseScale = false
btn2.setImage(img2, forState: .Normal)
btn2.setImage(img2, forState: .Highlighted)
// Search button.
let img3: UIImage? = UIImage(named: "ic_search_white")
let btn3: FlatButton = FlatButton()
btn3.pulseColor = MaterialColor.white
btn3.pulseFill = true
btn3.pulseScale = false
btn3.setImage(img3, forState: .Normal)
btn3.setImage(img3, forState: .Highlighted)
// Add buttons to left side.
navigationBarView.leftButtons = [btn1]
// Add buttons to right side.
navigationBarView.rightButtons = [btn2, btn3]
// To support orientation changes, use MaterialLayout.
view.addSubview(navigationBarView)
navigationBarView.translatesAutoresizingMaskIntoConstraints = false
MaterialLayout.alignFromTop(view, child: navigationBarView)
MaterialLayout.alignToParentHorizontally(view, child: navigationBarView)
MaterialLayout.height(view, child: navigationBarView, height: 70)
```
<a name="sortedset"></a>
### SortedSet
SortedSets are a powerful data structure for algorithm and analysis design. Elements within a SortedSet are unique and insert, remove, and search operations have a complexity of O(logn). The GraphKit implementation of a SortedSet also includes an order-statistic, which allows the data structure to be accessed using an index subscript like an array. Below are examples of its usage.
<a name="sidenavigationviewcontroller"></a>
### SideNavigationViewController
```swift
let graph: Graph = Graph()
As elegant as is effective, the SideNavigationViewController is an excellent way to organize your app. In the Examples directory, there is an example project using this wonderful component.
let setA: SortedSet<Bond> = SortedSet<Bond>(elements: graph.searchForBond(types: ["Author"]))
let setB: SortedSet<Bond> = SortedSet<Bond>(elements: graph.searchForBond(types: ["Director"]))
![MaterialKitSideNavigationViewController](http://www.materialkit.io/MK/MaterialKitSideNavigationViewController.gif)
let setC: SortedSet<Entity> = SortedSet<Entity>(elements: graph.searchForEntity(groups: ["Physics"]))
let setD: SortedSet<Entity> = SortedSet<Entity>(elements: graph.searchForEntity(groups: ["Math"]))
<a name="captureview"></a>
### CaptureView
let setE: SortedSet<Entity> = SortedSet<Entity>(elements: graph.searchForEntity(types: ["User"]))
Add a new dimension of interactivity with CaptureView. CaptureView is a fully functional camera that is completely customizable.
// Union.
print((setA + setB).count) // Output: 3
print(setA.union(setB).count) // Output: 3
![MaterialKitCaptureView](http://www.materialkit.io/MK/MaterialKitCaptureView.jpg)
// Intersect.
print(setC.intersect(setD).count) // Output: 1
Checkout the Examples Programmatic directory for a sample project using this wonderful component.
// Subset.
print(setD < setC) // true
print(setD.isSubsetOf(setC)) // true
<a name="materialcolor"></a>
### MaterialColor
// Superset.
print(setD > setC) // false
print(setD.isSupersetOf(setC)) // false
MaterialColor is a complete Material Design color library. It uses base color values that expand to a range of lighter and darker shades, with the addition of accents.
// Contains.
print(setE.contains(setA.first!.subject!)) // true
![MaterialKitMaterialColorPalette](http://www.materialkit.io/MK/MaterialKitMaterialColorPalette.png)
// Probability.
print(setE.probabilityOf(setA.first!.subject!, setA.last!.subject!)) // 0.666666666666667
```swift
let button: FabButton = FabButton()
button.backgroundColor = MaterialColor.blue.darken1
```
<a name="sortedmultiset"></a>
### SortedMultiSet
A SortedMultiSet is identical to a SortedSet, except that a SortedMultiSet allows non-unique elements. Look at [SortedSet](#sortedset) for examples of its usage.
<a name="sorteddictionary"></a>
### SortedDictionary
[Learn More About MaterialColor](https://github.com/CosmicMind/MaterialKit/wiki/MaterialColor)
A SortedDictionary is a powerful data structure that maintains a sorted set of keys with value pairs. Keys within a SortedDictionary are unique and insert, remove, update, and search operations have a complexity of O(logn).
<a name="materiallayout"></a>
### MaterialLayout
<a name="sortedmultidictionary"></a>
### SortedMultiDictionary
MaterialLayout simplifies the use of AutoLayout. It offers a clean and expansive API that focuses on the intent of the desired layout.
A SortedMultiDictionary is identical to a SortedDictionary, except that a SortedMultiDictionary allows non-unique keys. Below is an example of its usage.
```swift
let graph: Graph = Graph()
let students: Array<Entity> = graph.searchForEntity(types: ["Student"])
let dict: SortedMultiDictionary<String, Entity> = SortedMultiDictionary<String, Entity>()
// Do something with an alphabetically SortedMultiDictionary of student Entity Objects.
for student in students {
dict.insert(student["name"] as! String, value: student)
}
```
[Learn More About MaterialLayout](https://github.com/CosmicMind/MaterialKit/wiki/MaterialLayout)
### License
......@@ -533,7 +658,7 @@ Redistribution and use in source and binary forms, with or without modification,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of GraphKit nor the names of its
* Neither the name of MaterialKit nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -250,7 +250,9 @@ public class TextField : UITextField {
public var titleLabelColor: UIColor? {
didSet {
titleLabel?.textColor = titleLabelColor
bottomBorderLayer.backgroundColor = titleLabelColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.titleLabelColor?.CGColor
}
}
}
......@@ -279,11 +281,15 @@ public class TextField : UITextField {
public var detailLabelHidden: Bool = false {
didSet {
if detailLabelHidden {
bottomBorderLayer.backgroundColor = editing ? titleLabelActiveColor?.CGColor : titleLabelColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.editing ? self.titleLabelActiveColor?.CGColor : self.titleLabelColor?.CGColor
}
hideDetailLabel()
} else {
detailLabel?.textColor = detailLabelActiveColor
bottomBorderLayer.backgroundColor = detailLabelActiveColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.detailLabelActiveColor?.CGColor
}
showDetailLabel()
}
}
......@@ -410,11 +416,15 @@ public class TextField : UITextField {
if 0 == text?.utf16.count {
titleLabel?.textColor = titleLabelColor
bottomBorderLayer.backgroundColor = titleLabelColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.titleLabelColor?.CGColor
}
detailLabelHidden = true
} else {
titleLabel?.textColor = titleLabelActiveColor
bottomBorderLayer.backgroundColor = detailLabelHidden ? titleLabelActiveColor?.CGColor : detailLabelActiveColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.detailLabelHidden ? self.titleLabelActiveColor?.CGColor : self.detailLabelActiveColor?.CGColor
}
}
}
......@@ -423,7 +433,9 @@ public class TextField : UITextField {
if 0 < text?.utf16.count {
showTitleLabel()
titleLabel?.textColor = titleLabelActiveColor
bottomBorderLayer.backgroundColor = detailLabelHidden ? titleLabelActiveColor?.CGColor : detailLabelActiveColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.detailLabelHidden ? self.titleLabelActiveColor?.CGColor : self.detailLabelActiveColor?.CGColor
}
} else if 0 == text?.utf16.count {
hideTitleLabel()
detailLabelHidden = true
......@@ -438,7 +450,9 @@ public class TextField : UITextField {
hideTitleLabel()
}
titleLabel?.textColor = titleLabelColor
bottomBorderLayer.backgroundColor = detailLabelHidden ? titleLabelColor?.CGColor : detailLabelActiveColor?.CGColor
MaterialAnimation.animationDisabled { [unowned self] in
self.bottomBorderLayer.backgroundColor = self.detailLabelHidden ? self.titleLabelColor?.CGColor : self.detailLabelActiveColor?.CGColor
}
}
/// Manages the layout for the shape of the view instance.
......
......@@ -419,22 +419,13 @@ public class TextView: UITextView {
/// Notification handler for when text editing began.
internal func handleTextViewTextDidBegin() {
if let v: UILabel = titleLabel {
if v.hidden {
let h: CGFloat = v.font.pointSize
v.frame = CGRectMake(0, -h, bounds.width, h)
v.text = placeholderLabel?.text
if 0 == text?.utf16.count {
v.textColor = titleLabelColor
} else {
v.textColor = titleLabelActiveColor
}
}
}
prepareTitleLabelForAnimation()
}
/// Notification handler for when text changed.
internal func handleTextViewTextDidChange() {
prepareTitleLabelForAnimation()
if let p = placeholderLabel {
p.hidden = !(true == text?.isEmpty)
}
......@@ -501,17 +492,35 @@ public class TextView: UITextView {
v.hidden = true
v.alpha = 0
}
titleLabel?.text = placeholderLabel?.text
addSubview(v)
}
}
/// Parepares the titleLabel before it animates.
private func prepareTitleLabelForAnimation() {
if let v: UILabel = titleLabel {
if v.hidden {
let h: CGFloat = v.font.pointSize
v.frame = CGRectMake(0, -h, bounds.width, h)
if let s: String = placeholderLabel?.text {
v.text = s
}
if 0 == text?.utf16.count {
v.textColor = titleLabelColor
} else {
v.textColor = titleLabelActiveColor
}
}
}
}
/// Shows and animates the titleLabel property.
private func showTitleLabel() {
if let v: UILabel = titleLabel {
v.hidden = false
UIView.animateWithDuration(0.25, animations: {
v.alpha = 1
print(v.frame)
v.frame.origin.y = -v.frame.height - 4
})
}
......
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