Compare commits

..
8 Commits
Author SHA1 Message Date
Abdurahim Jauzee dd71f7ba65 update podspec 2017-05-31 18:38:52 +03:00
Abdurahim Jauzee fecd05d93f - add unfold(_:animated:completion) method
- deprecate `selectedAnimation` because it’s name is not clear
- minor improvements
2017-05-31 18:38:06 +03:00
Abdurahim Jauzee 77e99b8708 update podspec 2017-05-31 12:41:22 +03:00
Abdurahim Jauzee 5254378736 remove unnecessary guard statement 2017-05-31 12:39:34 +03:00
Abdurahim Jauzee 74e0ca7f7b update podspec 2017-05-31 12:17:09 +03:00
Abdurahim Jauzee ef3307924a use animationDuration method 2017-05-31 12:14:37 +03:00
Abdurahim Jauzee 39377ad181 revert animationDuration method for backward compatibility 2017-05-31 12:09:19 +03:00
Abdurahim Jauzee 1cf7a8124f fix typos 2017-05-31 12:08:50 +03:00
3 changed files with 71 additions and 64 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FoldingCell'
s.version = '2.1.0'
s.version = '2.1.3'
s.summary = 'UITableViewCell with folding animation.'
s.homepage = 'https://github.com/Ramotion/folding-cell'
s.license = 'MIT'
@@ -27,6 +27,11 @@ class DemoCell: FoldingCell {
super.awakeFromNib()
}
override func animationDuration(_ itemIndex: NSInteger, type: FoldingCell.AnimationType) -> TimeInterval {
let durations = [0.26, 0.2, 0.2]
return durations[itemIndex]
}
}
// MARK: - Actions ⚡️
+65 -63
View File
@@ -93,7 +93,7 @@ open class FoldingCell: UITableViewCell {
}
containerViewTop.constant = foregroundViewTop.constant
containerView.alpha = 0;
containerView.alpha = 0
if let height = (foregroundView.constraints.filter { $0.firstAttribute == .height && $0.secondItem == nil}).first?.constant {
foregroundView.layer.anchorPoint = CGPoint(x: 0.5, y: 1)
@@ -101,7 +101,7 @@ open class FoldingCell: UITableViewCell {
}
foregroundView.layer.transform = foregroundView.transform3d()
createAnimationView();
createAnimationView()
self.contentView.bringSubview(toFront: foregroundView)
}
@@ -133,7 +133,7 @@ open class FoldingCell: UITableViewCell {
for view in animationViewSuperView.filter({$0 is RotatedView}) {
view.alpha = 0;
}
} else { // close
} else {
for case let view as RotatedView in animationViewSuperView.filter({$0 is RotatedView}) {
if animationType == .open {
view.alpha = 0
@@ -146,7 +146,6 @@ open class FoldingCell: UITableViewCell {
}
func createAnimationView() {
animationView = UIView(frame: containerView.frame)
animationView?.layer.cornerRadius = foregroundView.layer.cornerRadius
animationView?.backgroundColor = .clear
@@ -190,18 +189,18 @@ open class FoldingCell: UITableViewCell {
func addImageItemsToAnimationView() {
containerView.alpha = 1;
let contSize = containerView.bounds.size
let forgSize = foregroundView.bounds.size
let containerViewSize = containerView.bounds.size
let foregroundViewSize = foregroundView.bounds.size
// added first item
var image = containerView.pb_takeSnapshot(CGRect(x: 0, y: 0, width: contSize.width, height: forgSize.height))
var image = containerView.pb_takeSnapshot(CGRect(x: 0, y: 0, width: containerViewSize.width, height: foregroundViewSize.height))
var imageView = UIImageView(image: image)
imageView.tag = 0
imageView.layer.cornerRadius = foregroundView.layer.cornerRadius
animationView?.addSubview(imageView)
// added secod item
image = containerView.pb_takeSnapshot(CGRect(x: 0, y: forgSize.height, width: contSize.width, height: forgSize.height))
image = containerView.pb_takeSnapshot(CGRect(x: 0, y: foregroundViewSize.height, width: containerViewSize.width, height: foregroundViewSize.height))
imageView = UIImageView(image: image)
let rotatedView = RotatedView(frame: imageView.frame)
@@ -211,24 +210,24 @@ open class FoldingCell: UITableViewCell {
rotatedView.addSubview(imageView)
animationView?.addSubview(rotatedView)
rotatedView.frame = CGRect(x: imageView.frame.origin.x, y: forgSize.height, width: contSize.width, height: forgSize.height)
rotatedView.frame = CGRect(x: imageView.frame.origin.x, y: foregroundViewSize.height, width: containerViewSize.width, height: foregroundViewSize.height)
// added other views
let itemHeight = (contSize.height - 2 * forgSize.height) / CGFloat(itemCount - 2)
let itemHeight = (containerViewSize.height - 2 * foregroundViewSize.height) / CGFloat(itemCount - 2)
if itemCount == 2 {
// decrease containerView height or increase itemCount
assert(contSize.height - 2 * forgSize.height == 0, "contanerView.height too high")
assert(containerViewSize.height - 2 * foregroundViewSize.height == 0, "contanerView.height too high")
}
else{
// decrease containerView height or increase itemCount
assert(contSize.height - 2 * forgSize.height >= itemHeight, "contanerView.height too high")
assert(containerViewSize.height - 2 * foregroundViewSize.height >= itemHeight, "contanerView.height too high")
}
var yPosition = 2 * forgSize.height
var yPosition = 2 * foregroundViewSize.height
var tag = 2
for _ in 2..<itemCount {
image = containerView.pb_takeSnapshot(CGRect(x: 0, y: yPosition, width: contSize.width, height: itemHeight))
image = containerView.pb_takeSnapshot(CGRect(x: 0, y: yPosition, width: containerViewSize.width, height: itemHeight))
imageView = UIImageView(image: image)
let rotatedView = RotatedView(frame: imageView.frame)
@@ -241,18 +240,18 @@ open class FoldingCell: UITableViewCell {
rotatedView.tag = tag
yPosition += itemHeight
tag += 1;
tag += 1
}
containerView.alpha = 0;
if let animationView = self.animationView {
// added back view
var previusView: RotatedView?
for case let contener as RotatedView in animationView.subviews.sorted(by: { $0.tag < $1.tag })
where contener.tag > 0 && contener.tag < animationView.subviews.count {
previusView?.addBackView(contener.bounds.size.height, color: backViewColor)
previusView = contener
var previuosView: RotatedView?
for case let container as RotatedView in animationView.subviews.sorted(by: { $0.tag < $1.tag })
where container.tag > 0 && container.tag < animationView.subviews.count {
previuosView?.addBackView(container.bounds.size.height, color: backViewColor)
previuosView = container
}
}
animationItemViews = createAnimationItemView()
@@ -270,6 +269,21 @@ open class FoldingCell: UITableViewCell {
// MARK: public
/// Unfold cell.
///
/// - Parameters:
/// - value: unfold = true; collapse = false.
/// - animated: animate changes.
/// - completion: A block object to be executed when the animation sequence ends.
open func unfold(_ value: Bool, animated: Bool = true, completion: ((Void) -> Void)? = nil) {
if animated {
value ? openAnimation(completion) : closeAnimation(completion)
} else {
foregroundView.alpha = value ? 0 : 1
containerView.alpha = value ? 1 : 0
}
}
/**
Open or close cell
@@ -277,40 +291,29 @@ open class FoldingCell: UITableViewCell {
- parameter animated: Specify true if you want to animate the change in visibility or false if you want immediately.
- parameter completion: A block object to be executed when the animation sequence ends.
*/
@available(iOS, deprecated, message: "Use unfold(_:animated:completion) method instead.")
open func selectedAnimation(_ isSelected: Bool, animated: Bool, completion: ((Void) -> Void)?) {
if isSelected {
if animated {
containerView.alpha = 0;
openAnimation(completion)
} else {
foregroundView.alpha = 0
containerView.alpha = 1;
}
} else {
if animated {
closeAnimation(completion)
} else {
foregroundView.alpha = 1;
containerView.alpha = 0;
}
}
unfold(isSelected, animated: animated, completion: completion)
}
open func isAnimating()->Bool {
open func isAnimating() -> Bool {
return animationView?.alpha == 1 ? true : false
}
// MARK: animations
open var isUnfolded = false
// MARK: Animations
open func animationDuration(_ itemIndex: NSInteger, type: AnimationType) -> TimeInterval {
return type == .close ? durationsForCollapsedState[itemIndex] : durationsForExpandedState[itemIndex]
}
open var durationsForExpandedState: [TimeInterval] = []
open var durationsForCollapsedState: [TimeInterval] = []
func durationSequence(_ type: AnimationType)-> [TimeInterval] {
var durations = [TimeInterval]()
for i in 0..<itemCount-1 {
let duration = type == .close ? durationsForCollapsedState[i] : durationsForExpandedState[i]
let duration = animationDuration(i, type: type)
durations.append(TimeInterval(duration / 2.0))
durations.append(TimeInterval(duration / 2.0))
}
@@ -318,7 +321,7 @@ open class FoldingCell: UITableViewCell {
}
func openAnimation(_ completion: ((Void) -> Void)?) {
isUnfolded = true
removeImageItemsFromAnimationView()
addImageItemsToAnimationView()
@@ -326,12 +329,12 @@ open class FoldingCell: UITableViewCell {
return
}
animationView.alpha = 1;
containerView.alpha = 0;
animationView.alpha = 1
containerView.alpha = 0
let durations = durationSequence(.open)
var delay: TimeInterval = 0
var delay: TimeInterval = 0
var timing = kCAMediaTimingFunctionEaseIn
var from: CGFloat = 0.0;
var to: CGFloat = -CGFloat.pi / 2
@@ -354,22 +357,22 @@ open class FoldingCell: UITableViewCell {
delay += durations[index]
}
let firstItemView = animationView.subviews.filter{$0.tag == 0}.first
let firstItemView = animationView.subviews.filter { $0.tag == 0 }.first
firstItemView?.layer.masksToBounds = true
DispatchQueue.main.asyncAfter(deadline: .now() + durations[0], execute: {
firstItemView?.layer.cornerRadius = 0
})
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
self.animationView?.alpha = 0
self.containerView.alpha = 1
completion?()
})
}
}
func closeAnimation(_ completion: ((Void) -> Void)?) {
isUnfolded = false
removeImageItemsFromAnimationView()
addImageItemsToAnimationView()
@@ -377,14 +380,14 @@ open class FoldingCell: UITableViewCell {
fatalError()
}
animationView?.alpha = 1;
containerView.alpha = 0;
animationView?.alpha = 1
containerView.alpha = 0
var durations: [TimeInterval] = durationSequence(.close).reversed()
var delay: TimeInterval = 0
var delay: TimeInterval = 0
var timing = kCAMediaTimingFunctionEaseIn
var from: CGFloat = 0.0;
var from: CGFloat = 0.0
var to: CGFloat = CGFloat.pi / 2
var hidden = true
configureAnimationItems(.close)
@@ -408,7 +411,7 @@ open class FoldingCell: UITableViewCell {
completion?()
})
let firstItemView = animationView?.subviews.filter{$0.tag == 0}.first
let firstItemView = animationView?.subviews.filter { $0.tag == 0 }.first
firstItemView?.layer.cornerRadius = 0
firstItemView?.layer.masksToBounds = true
if let durationFirst = durations.first {
@@ -432,7 +435,7 @@ open class RotatedView: UIView {
view.backgroundColor = color
view.layer.anchorPoint = CGPoint.init(x: 0.5, y: 1)
view.layer.transform = view.transform3d()
view.translatesAutoresizingMaskIntoConstraints = false;
view.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(view)
backView = view
@@ -498,23 +501,22 @@ extension RotatedView: CAAnimationDelegate {
self.layer.shouldRasterize = false
self.rotatedX(CGFloat(0))
}
}
extension UIView {
private extension UIView {
func pb_takeSnapshot(_ frame: CGRect) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0.0)
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.translateBy(x: frame.origin.x * -1, y: frame.origin.y * -1)
guard let currentContext = UIGraphicsGetCurrentContext() else {
return nil
}
self.layer.render(in: currentContext)
layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}