Commit e73889da by Daniel Dahan

added BasicCollectionViewCell

parent bddc2ee5
......@@ -58,6 +58,8 @@
964B17D51BBB31C2002A9CA0 /* MaterialAnimation.swift in Headers */ = {isa = PBXBuildFile; fileRef = 65BDD1731BB8D443006F7F2B /* MaterialAnimation.swift */; settings = {ATTRIBUTES = (Public, ); }; };
964B17D61BBB31C2002A9CA0 /* MaterialLayout.swift in Headers */ = {isa = PBXBuildFile; fileRef = 964B17B31BBA447F002A9CA0 /* MaterialLayout.swift */; settings = {ATTRIBUTES = (Public, ); }; };
964B17D91BBB3911002A9CA0 /* BasicCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964B17D81BBB3911002A9CA0 /* BasicCardView.swift */; settings = {ASSET_TAGS = (); }; };
965C17C51BC8273D00B1059A /* MaterialCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965C17C41BC8273D00B1059A /* MaterialCollectionViewCell.swift */; settings = {ASSET_TAGS = (); }; };
965C17C71BC8279F00B1059A /* BasicCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965C17C61BC8279F00B1059A /* BasicCollectionViewCell.swift */; settings = {ASSET_TAGS = (); }; };
9699879C1BC5FE49006D678E /* MaterialTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */; settings = {ASSET_TAGS = (); }; };
96C4FABE1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */; settings = {ASSET_TAGS = (); }; };
96D26BFD1BC23649006478BD /* ImageCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D26BFC1BC23649006478BD /* ImageCardView.swift */; settings = {ASSET_TAGS = (); }; };
......@@ -111,6 +113,8 @@
964B17B31BBA447F002A9CA0 /* MaterialLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialLayout.swift; sourceTree = "<group>"; };
964B17B51BBA4BEA002A9CA0 /* MaterialStatusBarStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialStatusBarStyle.swift; sourceTree = "<group>"; };
964B17D81BBB3911002A9CA0 /* BasicCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCardView.swift; sourceTree = "<group>"; };
965C17C41BC8273D00B1059A /* MaterialCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialCollectionViewCell.swift; sourceTree = "<group>"; };
965C17C61BC8279F00B1059A /* BasicCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCollectionViewCell.swift; sourceTree = "<group>"; };
9699879B1BC5FE49006D678E /* MaterialTextLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTextLayer.swift; sourceTree = "<group>"; };
96C4FABD1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaterialTransitionAnimation.swift; sourceTree = "<group>"; };
96D26BFC1BC23649006478BD /* ImageCardView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCardView.swift; sourceTree = "<group>"; };
......@@ -230,6 +234,7 @@
65BDD1551BB6FC60006F7F2B /* Button */,
65BDD1701BB8CD56006F7F2B /* Label */,
964B17D71BBB38E2002A9CA0 /* Card */,
965C17C31BC8272700B1059A /* Collection */,
65BDD1751BB8D44B006F7F2B /* Animation */,
964B17B21BBA445D002A9CA0 /* Layout */,
);
......@@ -286,6 +291,15 @@
name = Navigation;
sourceTree = "<group>";
};
965C17C31BC8272700B1059A /* Collection */ = {
isa = PBXGroup;
children = (
965C17C41BC8273D00B1059A /* MaterialCollectionViewCell.swift */,
965C17C61BC8279F00B1059A /* BasicCollectionViewCell.swift */,
);
name = Collection;
sourceTree = "<group>";
};
96B57D4C1B90AF6A00DE7BBB /* Theme */ = {
isa = PBXGroup;
children = (
......@@ -467,10 +481,12 @@
65BDD1741BB8D443006F7F2B /* MaterialAnimation.swift in Sources */,
65BDD14B1BB5DD02006F7F2B /* MaterialFont.swift in Sources */,
9699879C1BC5FE49006D678E /* MaterialTextLayer.swift in Sources */,
965C17C51BC8273D00B1059A /* MaterialCollectionViewCell.swift in Sources */,
65BDD16A1BB7146B006F7F2B /* MaterialBorder.swift in Sources */,
65BDD15B1BB7095E006F7F2B /* MaterialRadius.swift in Sources */,
65BDD1721BB8CD77006F7F2B /* MaterialLabel.swift in Sources */,
65BDD1491BB5DC98006F7F2B /* MaterialColor.swift in Sources */,
965C17C71BC8279F00B1059A /* BasicCollectionViewCell.swift in Sources */,
96C4FABE1BC3168900E4FFC3 /* MaterialTransitionAnimation.swift in Sources */,
65D2BEC91BBED1FA00800B7B /* MaterialKeyframeAnimation.swift in Sources */,
65D2BEC71BBED1E400800B7B /* MaterialBasicAnimation.swift in Sources */,
......
//
// Copyright (C) 2015 GraphKit, Inc. <http://graphkit.io> and other GraphKit contributors.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
public class BasicCollectionViewCell : MaterialCollectionViewCell {
/**
:name: titleLayer
*/
public private(set) lazy var titleLayer: MaterialTextLayer = MaterialTextLayer()
/**
:name: detailLayer
*/
public private(set) lazy var detailLayer: MaterialTextLayer = MaterialTextLayer()
/**
:name: leftLayer
*/
public private(set) lazy var leftLayer: MaterialLayer = MaterialLayer()
/**
:name: rightLayer
*/
public private(set) lazy var rightLayer: MaterialLayer = MaterialLayer()
//
// :name: prepareView
//
internal override func prepareView() {
super.prepareView()
// title
layer.addSublayer(titleLayer)
// detail
layer.addSublayer(detailLayer)
// left
leftLayer.frame = CGRectMake(-width, 0, width, height)
layer.addSublayer(leftLayer)
// right
rightLayer.frame = CGRectMake(width, 0, width, height)
layer.addSublayer(rightLayer)
}
}
//
// Copyright (C) 2015 GraphKit, Inc. <http://graphkit.io> and other GraphKit contributors.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program located at the root of the software package
// in a file called LICENSE. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
public class MaterialCollectionViewCell : UICollectionViewCell, UIGestureRecognizerDelegate {
//
// :name: panRecognizer
//
private var panRecognizer: UIPanGestureRecognizer!
//
// :name: leftOnDragRelease
//
private var leftOnDragRelease: Bool = false
//
// :name: rightOnDragRelease
//
private var rightOnDragRelease: Bool = false
//
// :name: originalPosition
//
private var originalPosition: CGPoint!
/**
:name: visualLayer
*/
public private(set) lazy var visualLayer: CAShapeLayer = CAShapeLayer()
/**
:name: pulseLayer
*/
public private(set) lazy var pulseLayer: CAShapeLayer = CAShapeLayer()
/**
:name: delegate
*/
public weak var delegate: MaterialAnimationDelegate?
/**
:name: pulseScale
*/
public lazy var pulseScale: Bool = true
/**
:name: pulseColorOpacity
*/
public var pulseColorOpacity: CGFloat = MaterialTheme.pulseView.pulseColorOpacity {
didSet {
preparePulseLayer()
}
}
/**
:name: pulseColor
*/
public var pulseColor: UIColor? {
didSet {
preparePulseLayer()
}
}
/**
:name: backgroundColor
*/
public override var backgroundColor: UIColor? {
didSet {
layer.backgroundColor = backgroundColor?.CGColor
}
}
/**
:name: x
*/
public var x: CGFloat {
get {
return frame.origin.x
}
set(value) {
frame.origin.x = value
}
}
/**
:name: y
*/
public var y: CGFloat {
get {
return frame.origin.y
}
set(value) {
frame.origin.y = value
}
}
/**
:name: width
*/
public var width: CGFloat {
get {
return frame.size.width
}
set(value) {
frame.size.width = value
if .None != shape {
frame.size.height = value
}
}
}
/**
:name: height
*/
public var height: CGFloat {
get {
return frame.size.height
}
set(value) {
frame.size.height = value
if .None != shape {
frame.size.width = value
}
}
}
/**
:name: shadowColor
*/
public var shadowColor: UIColor? {
didSet {
layer.shadowColor = shadowColor?.CGColor
}
}
/**
:name: shadowOffset
*/
public var shadowOffset: CGSize {
get {
return layer.shadowOffset
}
set(value) {
layer.shadowOffset = value
}
}
/**
:name: shadowOpacity
*/
public var shadowOpacity: Float {
get {
return layer.shadowOpacity
}
set(value) {
layer.shadowOpacity = value
}
}
/**
:name: shadowRadius
*/
public var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set(value) {
layer.shadowRadius = value
}
}
/**
:name: masksToBounds
*/
public var masksToBounds: Bool {
get {
return visualLayer.masksToBounds
}
set(value) {
visualLayer.masksToBounds = value
}
}
/**
:name: cornerRadius
*/
public var cornerRadius: MaterialRadius? {
didSet {
if let v: MaterialRadius = cornerRadius {
layer.cornerRadius = MaterialRadiusToValue(v)
if .Circle == shape {
shape = .None
}
}
}
}
/**
:name: shape
*/
public var shape: MaterialShape {
didSet {
if .None != shape {
if width < height {
frame.size.width = height
} else {
frame.size.height = width
}
}
}
}
/**
:name: borderWidth
*/
public var borderWidth: MaterialBorder {
didSet {
layer.borderWidth = MaterialBorderToValue(borderWidth)
}
}
/**
:name: borderColor
*/
public var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.CGColor
}
}
/**
:name: shadowDepth
*/
public var shadowDepth: MaterialDepth {
didSet {
let value: MaterialDepthType = MaterialDepthToValue(shadowDepth)
shadowOffset = value.offset
shadowOpacity = value.opacity
shadowRadius = value.radius
}
}
/**
:name: position
*/
public var position: CGPoint {
get {
return layer.position
}
set(value) {
layer.position = value
}
}
/**
:name: zPosition
*/
public var zPosition: CGFloat {
get {
return layer.zPosition
}
set(value) {
layer.zPosition = value
}
}
/**
:name: init
*/
public required init?(coder aDecoder: NSCoder) {
borderWidth = .None
shadowDepth = .None
shape = .None
super.init(coder: aDecoder)
}
/**
:name: init
*/
public override init(frame: CGRect) {
borderWidth = .None
shadowDepth = .None
shape = .None
super.init(frame: frame)
prepareView()
}
/**
:name: init
*/
public convenience init() {
self.init(frame: CGRectNull)
}
/**
:name: layoutSubviews
*/
public override func layoutSubviews() {
super.layoutSubviews()
prepareShape()
visualLayer.frame = bounds
visualLayer.position = CGPointMake(width / 2, height / 2)
visualLayer.cornerRadius = layer.cornerRadius
}
/**
:name: animation
*/
public func animation(animation: CAAnimation) {
animation.delegate = self
if let a: CABasicAnimation = animation as? CABasicAnimation {
a.fromValue = (nil == layer.presentationLayer() ? layer : layer.presentationLayer() as! CALayer).valueForKeyPath(a.keyPath!)
}
if let a: CAPropertyAnimation = animation as? CAPropertyAnimation {
layer.addAnimation(a, forKey: a.keyPath!)
} else if let a: CAAnimationGroup = animation as? CAAnimationGroup {
layer.addAnimation(a, forKey: nil)
} else if let a: CATransition = animation as? CATransition {
layer.addAnimation(a, forKey: kCATransition)
}
}
/**
:name: animationDidStart
*/
public override func animationDidStart(anim: CAAnimation) {
delegate?.materialAnimationDidStart?(anim)
}
/**
:name: animationDidStop
*/
public override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
if let a: CAPropertyAnimation = anim as? CAPropertyAnimation {
if let b: CABasicAnimation = a as? CABasicAnimation {
MaterialAnimation.animationDisabled({
self.layer.setValue(nil == b.toValue ? b.byValue : b.toValue, forKey: b.keyPath!)
})
}
delegate?.materialAnimationDidStop?(anim, finished: flag)
layer.removeAnimationForKey(a.keyPath!)
} else if let a: CAAnimationGroup = anim as? CAAnimationGroup {
for x in a.animations! {
animationDidStop(x, finished: true)
}
}
}
/**
:name: touchesBegan
*/
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
let point: CGPoint = layer.convertPoint(touches.first!.locationInView(self), fromLayer: layer)
if true == layer.containsPoint(point) {
let w: CGFloat = width
let h: CGFloat = height
let r: CGFloat = 1.05
let t: CFTimeInterval = 0.25
if nil != pulseColor && 0 < pulseColorOpacity {
MaterialAnimation.animationDisabled({
self.pulseLayer.bounds = CGRectMake(0, 0, 2 * w, 2 * h)
})
MaterialAnimation.animationWithDuration(t, animations: {
self.pulseLayer.hidden = false
})
}
if pulseScale {
layer.addAnimation(MaterialAnimation.scale(r, duration: t), forKey: nil)
}
}
}
/**
:name: touchesMoved
*/
public override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesMoved(touches, withEvent: event)
}
/**
:name: touchesEnded
*/
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
shrink()
}
/**
:name: touchesCancelled
*/
public override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
shrink()
}
//
// :name: gestureRecognizerShouldBegin
//
public override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
let translation = panGestureRecognizer.translationInView(superview!)
return fabs(translation.x) > fabs(translation.y)
}
return false
}
//
// :name: handlePanGesture
//
internal func handlePanGesture(recognizer: UIPanGestureRecognizer) {
switch recognizer.state {
case .Began:
originalPosition = position
rightOnDragRelease = x < -width / 2
leftOnDragRelease = x > width / 2
case .Changed:
let translation = recognizer.translationInView(self)
MaterialAnimation.animationDisabled({
self.position.x = self.originalPosition.x + translation.x
})
rightOnDragRelease = x < -width / 2
leftOnDragRelease = x > width / 2
case .Ended:
// snap back
let a: CABasicAnimation = MaterialAnimation.position(CGPointMake(width / 2, y + height / 2), duration: 0.25)
a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
animation(a)
if rightOnDragRelease {
} else if leftOnDragRelease {
}
default:
break
}
}
//
// :name: prepareView
//
internal func prepareView() {
userInteractionEnabled = MaterialTheme.flatButton.userInteractionEnabled
backgroundColor = MaterialTheme.flatButton.backgroundColor
pulseColorOpacity = MaterialTheme.flatButton.pulseColorOpacity
pulseColor = MaterialTheme.flatButton.pulseColor
shadowDepth = MaterialTheme.flatButton.shadowDepth
shadowColor = MaterialTheme.flatButton.shadowColor
zPosition = MaterialTheme.flatButton.zPosition
masksToBounds = MaterialTheme.flatButton.masksToBounds
cornerRadius = MaterialTheme.flatButton.cornerRadius
borderWidth = MaterialTheme.flatButton.borderWidth
borderColor = MaterialTheme.flatButton.bordercolor
shape = MaterialTheme.flatButton.shape
// visualLayer
visualLayer.zPosition = -1
layer.addSublayer(visualLayer)
// pulseLayer
pulseLayer.hidden = true
pulseLayer.zPosition = 1
visualLayer.addSublayer(pulseLayer)
// gesture
panRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
panRecognizer.delegate = self
addGestureRecognizer(panRecognizer)
}
//
// :name: prepareShape
//
internal func prepareShape() {
if .Circle == shape {
layer.cornerRadius = width / 2
}
}
//
// :name: preparePulseLayer
//
internal func preparePulseLayer() {
pulseLayer.backgroundColor = pulseColor?.colorWithAlphaComponent(pulseColorOpacity).CGColor
}
//
// :name: shrink
//
internal func shrink() {
let t: CFTimeInterval = 0.25
if nil != pulseColor && 0 < pulseColorOpacity {
MaterialAnimation.animationWithDuration(t, animations: {
self.pulseLayer.hidden = true
})
}
if pulseScale {
layer.addAnimation(MaterialAnimation.scale(1, duration: t), forKey: nil)
}
}
}
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