[ADD] splitflap:fontForFlapAtIndex: method to customize the flap fonts
This commit is contained in:
parent
cbf2dcf95f
commit
4551eb28d4
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,11 +1,15 @@
|
|||
# Change log
|
||||
|
||||
## Version 0.2.0 (Under Developement)
|
||||
|
||||
- [ADD] `splitflap:fontForFlapAtIndex:` method to customize the flap fonts
|
||||
|
||||
## [Version 0.1.0](https://github.com/yannickl/Splitflap/releases/tag/0.1.0)
|
||||
Released on 2015-11-11.
|
||||
|
||||
- Supports "character" tokens
|
||||
- Can configure the number of flaps
|
||||
- Can configure the spacing between flaps
|
||||
- Can configure the rotation animation duration for each flaps
|
||||
- `flapSpacing` property to configure the spacing between flaps
|
||||
- `supportedTokensInSplitflap:` method to define the "characters" used by flaps
|
||||
- `numberOfFlapsInSplitflap:` to set the number of flaps
|
||||
- `splitflap(splitflap:rotationDurationForFlapAtIndex:` method to change the rotation duration of each flaps
|
||||
- Cocoapods support
|
||||
- Carthage support
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
CE525D971BF3833F00429200 /* SplitflapDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE525D791BF331D100429200 /* SplitflapDataSource.swift */; };
|
||||
CE525D981BF3833F00429200 /* SplitflapDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE525D7B1BF336EA00429200 /* SplitflapDelegate.swift */; };
|
||||
CE525D991BF3833F00429200 /* SplitflapTokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE525D7D1BF340BB00429200 /* SplitflapTokens.swift */; };
|
||||
CE525D9A1BF3833F00429200 /* Tile.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139B91BF266FC00DE6BA9 /* Tile.swift */; };
|
||||
CE525D9A1BF3833F00429200 /* TileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139B91BF266FC00DE6BA9 /* TileView.swift */; };
|
||||
CE525D9B1BF3833F00429200 /* TokenGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE525D7F1BF3425C00429200 /* TokenGenerator.swift */; };
|
||||
CE525D9C1BF3833F00429200 /* TokenParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE525D811BF3467D00429200 /* TokenParser.swift */; };
|
||||
CEB139A41BF266DD00DE6BA9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139A31BF266DD00DE6BA9 /* AppDelegate.swift */; };
|
||||
|
@ -29,7 +29,7 @@
|
|||
CEB139AB1BF266DD00DE6BA9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CEB139AA1BF266DD00DE6BA9 /* Assets.xcassets */; };
|
||||
CEB139AE1BF266DD00DE6BA9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CEB139AC1BF266DD00DE6BA9 /* LaunchScreen.storyboard */; };
|
||||
CEB139BD1BF266FC00DE6BA9 /* Splitflap.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139B81BF266FC00DE6BA9 /* Splitflap.swift */; };
|
||||
CEB139BE1BF266FC00DE6BA9 /* Tile.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139B91BF266FC00DE6BA9 /* Tile.swift */; };
|
||||
CEB139BE1BF266FC00DE6BA9 /* TileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139B91BF266FC00DE6BA9 /* TileView.swift */; };
|
||||
CEB139BF1BF266FC00DE6BA9 /* FlapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB139BA1BF266FC00DE6BA9 /* FlapView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
@ -74,7 +74,7 @@
|
|||
CEB139AD1BF266DD00DE6BA9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
CEB139AF1BF266DD00DE6BA9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
CEB139B81BF266FC00DE6BA9 /* Splitflap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Splitflap.swift; sourceTree = "<group>"; };
|
||||
CEB139B91BF266FC00DE6BA9 /* Tile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tile.swift; sourceTree = "<group>"; };
|
||||
CEB139B91BF266FC00DE6BA9 /* TileView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TileView.swift; sourceTree = "<group>"; };
|
||||
CEB139BA1BF266FC00DE6BA9 /* FlapView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlapView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
@ -146,7 +146,7 @@
|
|||
CE525D791BF331D100429200 /* SplitflapDataSource.swift */,
|
||||
CE525D7B1BF336EA00429200 /* SplitflapDelegate.swift */,
|
||||
CE525D7D1BF340BB00429200 /* SplitflapTokens.swift */,
|
||||
CEB139B91BF266FC00DE6BA9 /* Tile.swift */,
|
||||
CEB139B91BF266FC00DE6BA9 /* TileView.swift */,
|
||||
CE525D7F1BF3425C00429200 /* TokenGenerator.swift */,
|
||||
CE525D811BF3467D00429200 /* TokenParser.swift */,
|
||||
);
|
||||
|
@ -271,7 +271,7 @@
|
|||
CE525D991BF3833F00429200 /* SplitflapTokens.swift in Sources */,
|
||||
CE525D9C1BF3833F00429200 /* TokenParser.swift in Sources */,
|
||||
CE525D951BF3833F00429200 /* FlapView.swift in Sources */,
|
||||
CE525D9A1BF3833F00429200 /* Tile.swift in Sources */,
|
||||
CE525D9A1BF3833F00429200 /* TileView.swift in Sources */,
|
||||
CE525D961BF3833F00429200 /* Splitflap.swift in Sources */,
|
||||
CE525D9B1BF3833F00429200 /* TokenGenerator.swift in Sources */,
|
||||
CE525D971BF3833F00429200 /* SplitflapDataSource.swift in Sources */,
|
||||
|
@ -287,7 +287,7 @@
|
|||
CE525D7C1BF336EA00429200 /* SplitflapDelegate.swift in Sources */,
|
||||
CEB139A61BF266DD00DE6BA9 /* ViewController.swift in Sources */,
|
||||
CEB139A41BF266DD00DE6BA9 /* AppDelegate.swift in Sources */,
|
||||
CEB139BE1BF266FC00DE6BA9 /* Tile.swift in Sources */,
|
||||
CEB139BE1BF266FC00DE6BA9 /* TileView.swift in Sources */,
|
||||
CE525D821BF3467D00429200 /* TokenParser.swift in Sources */,
|
||||
CE525D7A1BF331D100429200 /* SplitflapDataSource.swift in Sources */,
|
||||
CE525D801BF3425C00429200 /* TokenGenerator.swift in Sources */,
|
||||
|
|
|
@ -26,7 +26,7 @@ class ViewController: UIViewController, SplitflapDataSource, SplitflapDelegate {
|
|||
override func viewDidAppear(animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
//updateSplitFlapAction(actionButton)
|
||||
updateSplitFlapAction(actionButton)
|
||||
}
|
||||
|
||||
// MARK: - Action Methods
|
||||
|
@ -58,5 +58,9 @@ class ViewController: UIViewController, SplitflapDataSource, SplitflapDelegate {
|
|||
func splitflap(splitflap: Splitflap, rotationDurationForFlapAtIndex index: Int) -> Double {
|
||||
return 0.2
|
||||
}
|
||||
|
||||
func splitflap(splitflap: Splitflap, fontForFlapAtIndex index: Int) -> UIFont? {
|
||||
return UIFont(name: "Courier", size: 50)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ The first example is the simplest way to use the `Splitflap` component. Here how
|
|||
```swift
|
||||
import Splitflap
|
||||
|
||||
let splitflapView = Splitflap(frame: CGRectMake(0, 0, 200, 80))
|
||||
let splitflapView = Splitflap(frame: CGRectMake(0, 0, 370, 53))
|
||||
splitflapView.datasource = self
|
||||
|
||||
// Set the text to display by animating the flaps
|
||||
|
|
|
@ -32,17 +32,13 @@ import QuartzCore
|
|||
desired character or graphic.
|
||||
*/
|
||||
final class FlapView: UIView {
|
||||
private var topTicTile = Tile(position: .Top)
|
||||
private var bottomTicTile = Tile(position: .Bottom)
|
||||
private var topTacTile = Tile(position: .Top)
|
||||
private var bottomTacTile = Tile(position: .Bottom)
|
||||
// The tiles used to display and animate the flaps
|
||||
private var topTicTile = TileView(position: .Top)
|
||||
private var bottomTicTile = TileView(position: .Bottom)
|
||||
private var topTacTile = TileView(position: .Top)
|
||||
private var bottomTacTile = TileView(position: .Bottom)
|
||||
|
||||
private enum AnimationTime {
|
||||
case Tic
|
||||
case Tac
|
||||
}
|
||||
|
||||
private var animationTime = AnimationTime.Tac
|
||||
// MARK: - Working With Tokens
|
||||
|
||||
var tokens: [String] = [] {
|
||||
didSet {
|
||||
|
@ -52,6 +48,20 @@ final class FlapView: UIView {
|
|||
private var tokenGenerator = TokenGenerator(tokens: [])
|
||||
private var targetToken: String?
|
||||
|
||||
// MARK: - Configuring the Label of Tiles
|
||||
|
||||
/// The font of the flap's text.
|
||||
var font: UIFont? {
|
||||
didSet {
|
||||
topTicTile.font = font
|
||||
bottomTicTile.font = font
|
||||
topTacTile.font = font
|
||||
bottomTacTile.font = font
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Initializing a Flap View
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
|
@ -66,6 +76,18 @@ final class FlapView: UIView {
|
|||
setupAnimations()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
let topLeafFrame = CGRectMake(0, 0, bounds.width, bounds.height / 2)
|
||||
let bottomLeafFrame = CGRectMake(0, bounds.height / 2, bounds.width, bounds.height / 2)
|
||||
|
||||
topTicTile.frame = topLeafFrame
|
||||
bottomTicTile.frame = bottomLeafFrame
|
||||
topTacTile.frame = topLeafFrame
|
||||
bottomTacTile.frame = bottomLeafFrame
|
||||
}
|
||||
|
||||
// MARK: - Initializing the Flap View
|
||||
|
||||
private func setupViews() {
|
||||
|
@ -84,11 +106,20 @@ final class FlapView: UIView {
|
|||
|
||||
// MARK: - Settings the Animations
|
||||
|
||||
private let topAnim = CABasicAnimation(keyPath: "transform")
|
||||
private let bottomAnim = CABasicAnimation(keyPath: "transform")
|
||||
/// Defines the current time of the animation to know which tile to display.
|
||||
private enum AnimationTime {
|
||||
/// Tic time.
|
||||
case Tic
|
||||
/// Tac time.
|
||||
case Tac
|
||||
}
|
||||
|
||||
private var animationTime = AnimationTime.Tac
|
||||
private let topAnim = CABasicAnimation(keyPath: "transform")
|
||||
private let bottomAnim = CABasicAnimation(keyPath: "transform")
|
||||
|
||||
private func setupAnimations() {
|
||||
// Set perspective
|
||||
// Set the perspective
|
||||
let zDepth: CGFloat = 1000
|
||||
var skewedIdentityTransform = CATransform3DIdentity
|
||||
skewedIdentityTransform.m34 = 1 / -zDepth
|
||||
|
@ -108,18 +139,14 @@ final class FlapView: UIView {
|
|||
bottomAnim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
let topLeafFrame = CGRectMake(0, 0, bounds.width, bounds.height / 2)
|
||||
let bottomLeafFrame = CGRectMake(0, bounds.height / 2, bounds.width, bounds.height / 2)
|
||||
|
||||
topTicTile.frame = topLeafFrame
|
||||
bottomTicTile.frame = bottomLeafFrame
|
||||
topTacTile.frame = topLeafFrame
|
||||
bottomTacTile.frame = bottomLeafFrame
|
||||
}
|
||||
// MARK: - Animating the Flap View
|
||||
|
||||
/**
|
||||
Display the given token.
|
||||
|
||||
- parameter token: A token string.
|
||||
- parameter rotationDuration: If upper than 0, it animates the change.
|
||||
*/
|
||||
func displayToken(token: String?, rotationDuration: Double) {
|
||||
let sanitizedToken = token ?? tokenGenerator.firstToken
|
||||
|
||||
|
@ -138,6 +165,10 @@ final class FlapView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Method used in conjunction with the `animationDidStop:finished:` callback in
|
||||
order to display all the tokens between the current one and the target one.
|
||||
*/
|
||||
private func displayNextToken() {
|
||||
guard tokenGenerator.currentElement != targetToken else {
|
||||
return
|
||||
|
@ -148,11 +179,11 @@ final class FlapView: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
/// Display the given token. If animated it rotate the flaps.
|
||||
private func updateWithToken(token: String, animated: Bool) {
|
||||
let topBack = animationTime == .Tic ? topTicTile : topTacTile
|
||||
let bottomBack = animationTime == .Tic ? bottomTicTile : bottomTacTile
|
||||
let topFront = animationTime == .Tic ? topTacTile : topTicTile
|
||||
let bottomFront = animationTime == .Tic ? bottomTacTile : bottomTicTile
|
||||
let topBack = animationTime == .Tic ? topTicTile : topTacTile
|
||||
let bottomBack = animationTime == .Tic ? bottomTicTile : bottomTacTile
|
||||
let topFront = animationTime == .Tic ? topTacTile : topTicTile
|
||||
|
||||
topBack.symbol = token
|
||||
bottomBack.symbol = token
|
||||
|
@ -160,7 +191,6 @@ final class FlapView: UIView {
|
|||
topBack.layer.removeAllAnimations()
|
||||
bottomBack.layer.removeAllAnimations()
|
||||
topFront.layer.removeAllAnimations()
|
||||
bottomFront.layer.removeAllAnimations()
|
||||
|
||||
if animated {
|
||||
bringSubviewToFront(topFront)
|
||||
|
|
|
@ -175,11 +175,14 @@ import UIKit
|
|||
|
||||
/// Rebuild and layout the split-flap view.
|
||||
private func updateAndLayoutView() {
|
||||
let targetDelegate = (delgate ?? self)
|
||||
|
||||
var tmp: [FlapView] = []
|
||||
|
||||
for _ in 0 ..< numberOfFlaps {
|
||||
for index in 0 ..< numberOfFlaps {
|
||||
let flap = FlapView()
|
||||
flap.tokens = tokens
|
||||
flap.font = targetDelegate.splitflap(self, fontForFlapAtIndex: index)
|
||||
|
||||
tmp.append(flap)
|
||||
addSubview(flap)
|
||||
|
@ -210,6 +213,7 @@ import UIKit
|
|||
|
||||
/// Default implementation of SplitflapDataSource
|
||||
extension Splitflap: SplitflapDataSource {
|
||||
/// By default the Splitflap object does not have flaps, so returns 0.
|
||||
public func numberOfFlapsInSplitflap(splitflap: Splitflap) -> Int {
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -45,12 +45,30 @@ public protocol SplitflapDelegate: class {
|
|||
- returns: The duration of the flap rotation in seconds.
|
||||
*/
|
||||
func splitflap(splitflap: Splitflap, rotationDurationForFlapAtIndex index: Int) -> Double
|
||||
|
||||
// MARK: - Configuring the Label of Flaps
|
||||
|
||||
/**
|
||||
Called by the split-flap when it needs to create its flap subviews.
|
||||
|
||||
- parameter splitflap: The split-flap view requesting the data.
|
||||
- parameter index: A zero-indexed number identifying a flap. The index starts
|
||||
at 0 for the leftmost flap.
|
||||
- returns: The font of the flap's text. If it returns nil, the flap uses its
|
||||
internal *Courier* font.
|
||||
*/
|
||||
func splitflap(splitflap: Splitflap, fontForFlapAtIndex index: Int) -> UIFont?
|
||||
}
|
||||
|
||||
/// Default implementation of SplitflapDelegate
|
||||
public extension SplitflapDelegate {
|
||||
/// Returns by default 0.2 seconds
|
||||
/// Returns by default 0.2 seconds.
|
||||
func splitflap(splitflap: Splitflap, rotationDurationForFlapAtIndex index: Int) -> Double {
|
||||
return 0.2
|
||||
}
|
||||
|
||||
/// Returns nil by default to use the internal flap's font.
|
||||
func splitflap(splitflap: Splitflap, fontForFlapAtIndex index: Int) -> UIFont? {
|
||||
return nil
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ import UIKit
|
|||
A Tile is an half view representing the flap's leaf. A tile can represents the
|
||||
top or the bottom of a leaf.
|
||||
*/
|
||||
final class Tile: UIView {
|
||||
final class TileView: UIView {
|
||||
private let digitLabel = UILabel()
|
||||
private let mainLineView = UIView()
|
||||
private let secondaryLineView = UIView()
|
||||
|
@ -54,6 +54,17 @@ final class Tile: UIView {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Configuring the Label
|
||||
|
||||
/// The font of the tile's text.
|
||||
var font: UIFont? {
|
||||
didSet {
|
||||
layoutSubviews()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Initializing a Flap View
|
||||
|
||||
convenience init(position: Position) {
|
||||
self.init(frame: CGRectZero)
|
||||
|
||||
|
@ -90,6 +101,8 @@ final class Tile: UIView {
|
|||
addSubview(secondaryLineView)
|
||||
}
|
||||
|
||||
// MARK: - Laying out Subviews
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
|
@ -126,7 +139,7 @@ final class Tile: UIView {
|
|||
}
|
||||
|
||||
digitLabel.frame = digitLabelFrame
|
||||
digitLabel.font = UIFont(name: "Courier", size: bounds.width)
|
||||
digitLabel.font = font ?? UIFont(name: "Courier", size: bounds.width)
|
||||
mainLineView.frame = mainLineViewFrame
|
||||
secondaryLineView.frame = secondaryLineViewFrame
|
||||
}
|
Loading…
Reference in New Issue