Update example project

This commit is contained in:
Yannick Loriot 2015-11-10 19:27:31 +01:00
parent 72fc873fed
commit 7d8a1f0822
5 changed files with 87 additions and 80 deletions

View File

@ -39,7 +39,7 @@
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="wheelCount">
<integer key="value" value="8"/>
<integer key="value" value="7"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="wheelSpacing">
<real key="value" value="2"/>

View File

@ -12,33 +12,27 @@ class ViewController: UIViewController {
@IBOutlet weak var splitflap: Splitflap!
@IBOutlet weak var actionButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
private let words = ["Hey You", "Bonsoir", "12h15", "Arrival"]
private var currentIndex = 0
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
updateSplitFlapAction(actionButton)
}
var i = 0
// MARK: - Action Methods
@IBAction func updateSplitFlapAction(sender: AnyObject) {
if i == 0 {
splitflap.text = "lol"
splitflap.setText(words[currentIndex], animated: true)
i++
}
else if i == 1 {
splitflap.text = "liligo"
currentIndex = (currentIndex + 1) % words.count
i++
}
else if i == 2 {
splitflap.text = "Azerty"
updateButtonWithTitle(words[currentIndex])
}
i++
}
else {
splitflap.text = "Hey You"
i = 0
}
private func updateButtonWithTitle(title: String) {
actionButton.setTitle("Say \(words[currentIndex])!", forState: .Normal)
}
}

View File

@ -60,6 +60,9 @@ class AlphaNumericAlphabet: Alphabet {
get {
return alphabets[currentIndex]
}
set(newValue) {
currentIndex = alphabets.indexOf(newValue) ?? currentIndex
}
}
func next() -> Element? {

View File

@ -1,34 +1,34 @@
/*
* Splitflap
*
* Copyright 2015-present Yannick Loriot.
* http://yannickloriot.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
* Splitflap
*
* Copyright 2015-present Yannick Loriot.
* http://yannickloriot.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
import UIKit
import QuartzCore
@IBDesignable public class Splitflap: UIView {
@IBInspectable var wheelCount: Int = 1 {
@IBInspectable public var wheelCount: Int = 1 {
didSet {
var wheels: [Wheel] = []
@ -40,9 +40,9 @@ import QuartzCore
}
}
@IBInspectable var wheelSpacing: CGFloat = 0
@IBInspectable public var wheelSpacing: CGFloat = 0
var animationDuration = Double(0.2) {
@IBInspectable public var animationDuration: Double = 0.2 {
didSet {
for wheel in wheels {
wheel.animationDuration = animationDuration
@ -51,26 +51,38 @@ import QuartzCore
}
var alphabet = AlphaNumericAlphabet()
var text: String? {
public var text: String? {
didSet {
if let t = text, let tokens = try? alphabet.parse(t) {
for (index, wheel) in wheels.enumerate() {
let token: String
setText(text, animated: false)
}
}
if index < tokens.count {
token = tokens[index]
}
else {
token = alphabet.emptyToken()
}
public func setText(text: String?, animated: Bool) {
let tokens: [String]
let delay = animationDuration / 1.1
if let t = text, let ts = try? alphabet.parse(t) {
tokens = ts
}
else {
tokens = []
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(index) * Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
wheel.displayToken(token, animated: true)
})
}
for (index, wheel) in wheels.enumerate() {
let token: String
if index < tokens.count {
token = tokens[index]
}
else {
token = alphabet.emptyToken()
}
let delay = animationDuration / 1.1
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(index) * Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
wheel.displayToken(token, animated: animated)
})
}
}

View File

@ -44,8 +44,8 @@ final class Wheel: UIView {
var animationDuration = Double(0.2)
private var targetToken: String = " "
var alphabet = AlphaNumericAlphabet()
private var targetToken: String?
override init(frame: CGRect) {
super.init(frame: frame)
@ -74,7 +74,7 @@ final class Wheel: UIView {
topTacTile.layer.anchorPoint = CGPointMake(0.5, 1.0)
bottomTacTile.layer.anchorPoint = CGPointMake(0.5, 0)
updateWithToken("", animated: false)
updateWithToken(alphabet.emptyToken(), animated: false)
}
private func setupAnimations() {
@ -111,22 +111,17 @@ final class Wheel: UIView {
bottomTacTile.frame = bottomLeafFrame
}
func tilesFromView(view: UIView) -> (top: UIView, bottom: UIView) {
let halfHeight = view.bounds.height / 2
let topHalfView = view.resizableSnapshotViewFromRect(CGRectMake(0, 0, view.bounds.width, halfHeight), afterScreenUpdates: true, withCapInsets: UIEdgeInsetsZero)
topHalfView.layer.anchorPoint = CGPointMake(0.5, 1.0)
let bottomHalfView = view.resizableSnapshotViewFromRect(CGRectMake(0, halfHeight, view.bounds.width, halfHeight), afterScreenUpdates: true, withCapInsets: UIEdgeInsetsZero)
bottomHalfView.layer.anchorPoint = CGPointMake(0.5, 0)
return (top: topHalfView, bottom: bottomHalfView)
}
func displayToken(token: String, animated: Bool) {
targetToken = token
if animated {
targetToken = token
displayNextToken()
displayNextToken()
}
else {
alphabet.currentElement = token
updateWithToken(token, animated: animated)
}
}
private func displayNextToken() {
@ -165,6 +160,9 @@ final class Wheel: UIView {
bottomBack.layer.addAnimation(bottomAnim, forKey: "bottomDownFlip")
}
else {
bringSubviewToFront(topBack)
bringSubviewToFront(bottomBack)
animationTime = animationTime == .Tic ? .Tac : .Tic
}
}