Compare commits

..
27 Commits
Author SHA1 Message Date
Alex K a4a918065d remove deprecated methods 2018-05-02 15:21:53 +03:00
Alex K dbaccb42b5 Merge branch 'master' of github.com:Ramotion/folding-cell 2018-05-02 15:15:43 +03:00
Alex K adbd6a608b Fixes #144 2018-05-02 15:15:34 +03:00
Ramotion f41fbfe98e Update README.md 2018-04-25 12:28:30 +03:00
Alex fd51a01d03 Update README.md 2018-04-23 09:26:46 +03:00
Ramotion 6f389b4850 Update README.md 2018-04-16 09:43:31 +03:00
Ramotion 9c1e834692 Update README.md 2018-04-09 09:44:30 +03:00
Ramotion da447982c8 Add files via upload 2018-04-09 09:43:35 +03:00
Alex K 816fe67543 update podspec 2018-04-02 10:21:06 +03:00
Alex K a191c4bc05 refactoring, remove guard with fatal error 2018-04-02 10:15:04 +03:00
Alex K cbe678277d update podspec 2018-03-27 16:37:34 +03:00
Alex K a760de74ee Fixes #126 make closeAnimation and opentAnimation methods public 2018-03-27 16:35:20 +03:00
Alex K 7d639d3332 update podspec 2018-03-27 16:32:23 +03:00
Alex K dc52176452 Fixes #62 2018-03-27 15:57:42 +03:00
Alex K 259e726146 Merge branch 'master' of github.com:Ramotion/folding-cell 2018-03-26 15:22:58 +03:00
Alex K 381fe89df9 Fix warning "The use of Swift 3 @objc inference in Swift 4 mode is deprecated. Please address deprecated @objc inference warnings" 2018-03-26 15:22:49 +03:00
Alex 99d7b642c9 Update README.md 2018-03-20 10:08:19 +03:00
Alex d5aa310bd6 Update README.md
remove duplicate Carthage badge
2018-03-12 14:07:00 +03:00
Ramotion df05fb3424 Update README.md 2018-03-01 11:31:32 +03:00
Ramotion f144e16433 Update README.md 2018-02-28 14:42:44 +03:00
Alex K c9c710f485 Merge branch 'master' of github.com:Ramotion/folding-cell 2018-02-27 17:13:13 +03:00
Alex K 49611acdf9 remove warnings in demo project 2018-02-27 17:13:06 +03:00
Denis Pakhaliuk 283afd04b2 Update README.md 2018-02-21 12:05:05 +03:00
Alex K 7cf93be5b7 remove unused code 2018-02-20 16:16:33 +03:00
Alex K ae01474fa4 update podspec 2018-02-14 09:33:54 +03:00
Alex K 16fa9ad54d remove unused code 2018-02-14 09:32:32 +03:00
Alex K 40d58abd2b update podspec 2018-02-07 11:53:05 +03:00
8 changed files with 176 additions and 160 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FoldingCell'
s.version = '3.0.1'
s.version = '3.0.6'
s.summary = 'UITableViewCell with folding animation.'
s.homepage = 'https://github.com/Ramotion/folding-cell'
s.license = 'MIT'
@@ -59,9 +59,12 @@
NSNumber *height = [self.cellHeights objectAtIndex:indexPath.row];
bool cellIsCollapsed = height.floatValue == self.kCloseCellHeight;
if (cellIsCollapsed) {
[(FoldingCell *) cell selectedAnimation:false animated:false completion: nil];
[(FoldingCell *)cell unfold:NO animated:NO completion:nil];
//[(FoldingCell *) cell selectedAnimation:false animated:false completion: nil];
} else {
[(FoldingCell *) cell selectedAnimation:true animated:false completion: nil];
[(FoldingCell *)cell unfold:YES animated:NO completion:nil];
//[(FoldingCell *) cell selectedAnimation:true animated:false completion: nil];
}
UIView *backgroundTopView = [cell viewWithTag:11];
@@ -108,11 +111,13 @@
bool cellIsCollapsed = height.floatValue == self.kCloseCellHeight;
if (cellIsCollapsed) {
[self.cellHeights setObject:[NSNumber numberWithFloat:self.kOpenCellHeight] atIndexedSubscript:indexPath.row];
[cell selectedAnimation:true animated:true completion: nil];
//[cell selectedAnimation:true animated:true completion: nil];
[cell unfold:YES animated:YES completion:nil];
duration = 0.5;
} else {
[self.cellHeights setObject:[NSNumber numberWithFloat:self.kCloseCellHeight] atIndexedSubscript:indexPath.row];
[cell selectedAnimation:false animated:true completion: nil];
//[cell selectedAnimation:false animated:true completion: nil];
[cell unfold:NO animated:YES completion:nil];
duration = 0.8;
}
@@ -305,7 +305,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "Alex K.";
TargetAttributes = {
8498513B1C5639F9006FA400 = {
@@ -322,6 +322,7 @@
9D57F31B1EDC7A6F0004599F = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = 34MUF9YXTA;
LastSwiftMigration = 0920;
ProvisioningStyle = Automatic;
};
9DAA51531EDDBAD700DFC539 = {
@@ -485,14 +486,22 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -531,14 +540,22 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -666,7 +683,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -687,7 +705,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "ramotion.com.FoldingCell-Demo";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -37,7 +36,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+126 -142
View File
@@ -25,27 +25,27 @@ import UIKit
/// UITableViewCell with folding animation
open class FoldingCell: UITableViewCell {
/// UIView whitch display when cell open
@IBOutlet open var containerView: UIView!
@IBOutlet open var containerViewTop: NSLayoutConstraint!
/// UIView whitch display when cell close
@IBOutlet open var foregroundView: RotatedView!
@IBOutlet open var foregroundViewTop: NSLayoutConstraint!
var animationView: UIView?
/// the number of folding elements. Default 2
@IBInspectable open var itemCount: NSInteger = 2
/// The color of the back cell
@IBInspectable open var backViewColor: UIColor = UIColor.brown
var animationItemViews: [RotatedView]?
/**
Folding animation types
- Open: Open direction
- Close: Close direction
*/
@@ -53,100 +53,100 @@ open class FoldingCell: UITableViewCell {
case open
case close
}
// MARK: Life Cycle
// MARK: Life Cycle
open override func awakeFromNib() {
super.awakeFromNib()
commonInit()
}
/**
Call this method in methods init(style: UITableViewCellStyle, reuseIdentifier: String?) after creating Views
*/
open func commonInit() {
configureDefaultState()
selectionStyle = .none
containerView.layer.cornerRadius = foregroundView.layer.cornerRadius
containerView.layer.masksToBounds = true
}
// MARK: configure
func configureDefaultState() {
guard let foregroundViewTop = self.foregroundViewTop,
let containerViewTop = self.containerViewTop else {
fatalError("set foregroundViewTop or containerViewTop outlets in storyboard")
fatalError("set foregroundViewTop or containerViewTop outlets in storyboard")
}
containerViewTop.constant = foregroundViewTop.constant
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)
foregroundViewTop.constant += height / 2
}
foregroundView.layer.transform = foregroundView.transform3d()
createAnimationView()
contentView.bringSubview(toFront: foregroundView)
}
func createAnimationItemView() -> [RotatedView] {
guard let animationView = self.animationView else {
fatalError()
}
var items = [RotatedView]()
items.append(foregroundView)
var rotatedViews = [RotatedView]()
for case let itemView as RotatedView in animationView.subviews.filter({ $0 is RotatedView }).sorted(by: { $0.tag < $1.tag }) {
rotatedViews.append(itemView)
if let backView = itemView.backView {
rotatedViews.append(backView)
}
animationView?.subviews
.compactMap({ $0 as? RotatedView })
.sorted(by: { $0.tag < $1.tag })
.forEach { itemView in
rotatedViews.append(itemView)
if let backView = itemView.backView {
rotatedViews.append(backView)
}
}
items.append(contentsOf: rotatedViews)
return items
}
func configureAnimationItems(_ animationType: AnimationType) {
guard let animationViewSuperView = animationView?.subviews else {
fatalError()
}
if animationType == .open {
for view in animationViewSuperView.filter({ $0 is RotatedView }) {
view.alpha = 0
}
animationView?.subviews
.compactMap { $0 as? RotatedView }
.forEach { $0.alpha = 0 }
} else {
for case let view as RotatedView in animationViewSuperView.filter({ $0 is RotatedView }) {
if animationType == .open {
view.alpha = 0
} else {
view.alpha = 1
view.backView?.alpha = 0
}
animationView?.subviews
.compactMap { $0 as? RotatedView }
.forEach {
if animationType == .open {
$0.alpha = 0
} else {
$0.alpha = 1
$0.backView?.alpha = 0
}
}
}
}
func createAnimationView() {
animationView = UIView(frame: containerView.frame)
animationView?.layer.cornerRadius = foregroundView.layer.cornerRadius
animationView?.backgroundColor = .clear
animationView?.translatesAutoresizingMaskIntoConstraints = false
animationView?.alpha = 0
guard let animationView = self.animationView else { return }
self.contentView.addSubview(animationView)
// copy constraints from containerView
var newConstraints = [NSLayoutConstraint]()
for constraint in self.contentView.constraints {
@@ -154,57 +154,57 @@ open class FoldingCell: UITableViewCell {
let newConstraint = NSLayoutConstraint(item: animationView, attribute: constraint.firstAttribute,
relatedBy: constraint.relation, toItem: constraint.secondItem, attribute: constraint.secondAttribute,
multiplier: constraint.multiplier, constant: constraint.constant)
newConstraints.append(newConstraint)
} else if let firstItem = constraint.firstItem as? UIView, let secondItem: UIView = constraint.secondItem as? UIView, secondItem == containerView {
let newConstraint = NSLayoutConstraint(item: firstItem, attribute: constraint.firstAttribute,
relatedBy: constraint.relation, toItem: animationView, attribute: constraint.secondAttribute,
multiplier: constraint.multiplier, constant: constraint.constant)
newConstraints.append(newConstraint)
}
}
self.contentView.addConstraints(newConstraints)
for constraint in containerView.constraints { // added height constraint
if constraint.firstAttribute == .height, let item: UIView = constraint.firstItem as? UIView, item == containerView {
let newConstraint = NSLayoutConstraint(item: animationView, attribute: constraint.firstAttribute,
relatedBy: constraint.relation, toItem: nil, attribute: constraint.secondAttribute,
multiplier: constraint.multiplier, constant: constraint.constant)
animationView.addConstraint(newConstraint)
}
}
}
func addImageItemsToAnimationView() {
containerView.alpha = 1
let containerViewSize = containerView.bounds.size
let foregroundViewSize = foregroundView.bounds.size
// added first item
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: foregroundViewSize.height, width: containerViewSize.width, height: foregroundViewSize.height))
imageView = UIImageView(image: image)
let rotatedView = RotatedView(frame: imageView.frame)
rotatedView.tag = 1
rotatedView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
rotatedView.layer.transform = rotatedView.transform3d()
rotatedView.addSubview(imageView)
animationView?.addSubview(rotatedView)
rotatedView.frame = CGRect(x: imageView.frame.origin.x, y: foregroundViewSize.height, width: containerViewSize.width, height: foregroundViewSize.height)
// added other views
let itemHeight = (containerViewSize.height - 2 * foregroundViewSize.height) / CGFloat(itemCount - 2)
if itemCount == 2 {
// decrease containerView height or increase itemCount
assert(containerViewSize.height - 2 * foregroundViewSize.height == 0, "contanerView.height too high")
@@ -212,58 +212,58 @@ open class FoldingCell: UITableViewCell {
// decrease containerView height or increase itemCount
assert(containerViewSize.height - 2 * foregroundViewSize.height >= itemHeight, "contanerView.height too high")
}
var yPosition = 2 * foregroundViewSize.height
var tag = 2
for _ in 2 ..< itemCount {
image = containerView.pb_takeSnapshot(CGRect(x: 0, y: yPosition, width: containerViewSize.width, height: itemHeight))
imageView = UIImageView(image: image)
let rotatedView = RotatedView(frame: imageView.frame)
rotatedView.addSubview(imageView)
rotatedView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
rotatedView.layer.transform = rotatedView.transform3d()
animationView?.addSubview(rotatedView)
rotatedView.frame = CGRect(x: 0, y: yPosition, width: rotatedView.bounds.size.width, height: itemHeight)
rotatedView.tag = tag
yPosition += itemHeight
tag += 1
}
containerView.alpha = 0
if let animationView = self.animationView {
// added back view
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
previuosView?.addBackView(container.bounds.size.height, color: backViewColor)
previuosView = container
}
}
animationItemViews = createAnimationItemView()
}
fileprivate func removeImageItemsFromAnimationView() {
guard let animationView = self.animationView else {
return
}
animationView.subviews.forEach({ $0.removeFromSuperview() })
}
// 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)? = nil) {
@objc open func unfold(_ value: Bool, animated: Bool = true, completion: (() -> Void)? = nil) {
if animated {
value ? openAnimation(completion) : closeAnimation(completion)
} else {
@@ -271,34 +271,22 @@ open class FoldingCell: UITableViewCell {
containerView.alpha = value ? 1 : 0
}
}
/**
Open or close cell
- parameter isSelected: Specify true if you want to open cell or false if you close cell.
- 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)?) {
unfold(isSelected, animated: animated, completion: completion)
}
open func isAnimating() -> Bool {
@objc open func isAnimating() -> Bool {
return animationView?.alpha == 1 ? true : false
}
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] = []
@objc open var durationsForExpandedState: [TimeInterval] = []
@objc open var durationsForCollapsedState: [TimeInterval] = []
func durationSequence(_ type: AnimationType) -> [TimeInterval] {
var durations = [TimeInterval]()
for i in 0 ..< itemCount - 1 {
@@ -308,87 +296,83 @@ open class FoldingCell: UITableViewCell {
}
return durations
}
func openAnimation(_ completion: (() -> Void)?) {
public func openAnimation(_ completion: (() -> Void)?) {
isUnfolded = true
removeImageItemsFromAnimationView()
addImageItemsToAnimationView()
guard let animationView = self.animationView else {
return
}
animationView.alpha = 1
animationView?.alpha = 1
containerView.alpha = 0
let durations = durationSequence(.open)
var delay: TimeInterval = 0
var timing = kCAMediaTimingFunctionEaseIn
var from: CGFloat = 0.0
var to: CGFloat = -CGFloat.pi / 2
var hidden = true
configureAnimationItems(.open)
guard let animationItemViews = self.animationItemViews else {
return
}
for index in 0 ..< animationItemViews.count {
let animatedView = animationItemViews[index]
animatedView.foldingAnimation(timing, from: from, to: to, duration: durations[index], delay: delay, hidden: hidden)
from = from == 0.0 ? CGFloat.pi / 2 : 0.0
to = to == 0.0 ? -CGFloat.pi / 2 : 0.0
timing = timing == kCAMediaTimingFunctionEaseIn ? kCAMediaTimingFunctionEaseOut : kCAMediaTimingFunctionEaseIn
hidden = !hidden
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: .now() + delay) {
self.animationView?.alpha = 0
self.containerView.alpha = 1
completion?()
}
}
func closeAnimation(_ completion: (() -> Void)?) {
public func closeAnimation(_ completion: (() -> Void)?) {
isUnfolded = false
removeImageItemsFromAnimationView()
addImageItemsToAnimationView()
guard let animationItemViews = self.animationItemViews else {
fatalError()
}
animationView?.alpha = 1
containerView.alpha = 0
var durations: [TimeInterval] = durationSequence(.close).reversed()
var delay: TimeInterval = 0
var timing = kCAMediaTimingFunctionEaseIn
var from: CGFloat = 0.0
var to: CGFloat = CGFloat.pi / 2
var hidden = true
configureAnimationItems(.close)
if durations.count < animationItemViews.count {
fatalError("wrong override func animationDuration(itemIndex:NSInteger, type:AnimationType)-> NSTimeInterval")
}
for index in 0 ..< animationItemViews.count {
let animatedView = animationItemViews.reversed()[index]
animatedView.foldingAnimation(timing, from: from, to: to, duration: durations[index], delay: delay, hidden: hidden)
to = to == 0.0 ? CGFloat.pi / 2 : 0.0
from = from == 0.0 ? -CGFloat.pi / 2 : 0.0
timing = timing == kCAMediaTimingFunctionEaseIn ? kCAMediaTimingFunctionEaseOut : kCAMediaTimingFunctionEaseIn
@@ -399,7 +383,7 @@ open class FoldingCell: UITableViewCell {
self.animationView?.alpha = 0
completion?()
})
let firstItemView = animationView?.subviews.filter { $0.tag == 0 }.first
firstItemView?.layer.cornerRadius = 0
firstItemView?.layer.masksToBounds = true
@@ -418,7 +402,7 @@ open class FoldingCell: UITableViewCell {
open class RotatedView: UIView {
var hiddenAfterAnimation = false
var backView: RotatedView?
func addBackView(_ height: CGFloat, color: UIColor) {
let view = RotatedView(frame: CGRect.zero)
view.backgroundColor = color
@@ -427,10 +411,10 @@ open class RotatedView: UIView {
view.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(view)
backView = view
view.addConstraint(NSLayoutConstraint(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height,
multiplier: 1, constant: height))
self.addConstraints([
NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1,
constant: self.bounds.size.height - height + height / 2),
@@ -438,12 +422,12 @@ open class RotatedView: UIView {
multiplier: 1, constant: 0),
NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing,
multiplier: 1, constant: 0),
])
])
}
}
extension RotatedView: CAAnimationDelegate {
func rotatedX(_ angle: CGFloat) {
var allTransofrom = CATransform3DIdentity
let rotateTransform = CATransform3DMakeRotation(angle, 1, 0, 0)
@@ -451,17 +435,17 @@ extension RotatedView: CAAnimationDelegate {
allTransofrom = CATransform3DConcat(allTransofrom, transform3d())
self.layer.transform = allTransofrom
}
func transform3d() -> CATransform3D {
var transform = CATransform3DIdentity
transform.m34 = 2.5 / -2000
return transform
}
// MARK: animations
func foldingAnimation(_ timing: String, from: CGFloat, to: CGFloat, duration: TimeInterval, delay: TimeInterval, hidden: Bool) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.x")
rotateAnimation.timingFunction = CAMediaTimingFunction(name: timing)
rotateAnimation.fromValue = from
@@ -471,17 +455,17 @@ extension RotatedView: CAAnimationDelegate {
rotateAnimation.fillMode = kCAFillModeForwards
rotateAnimation.isRemovedOnCompletion = false
rotateAnimation.beginTime = CACurrentMediaTime() + delay
self.hiddenAfterAnimation = hidden
self.layer.add(rotateAnimation, forKey: "rotation.x")
}
public func animationDidStart(_: CAAnimation) {
self.layer.shouldRasterize = true
self.alpha = 1
}
public func animationDidStop(_: CAAnimation, finished _: Bool) {
if hiddenAfterAnimation {
self.alpha = 0
@@ -493,17 +477,17 @@ extension RotatedView: CAAnimationDelegate {
}
private extension UIView {
func pb_takeSnapshot(_ frame: CGRect) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.translateBy(x: frame.origin.x * -1, y: frame.origin.y * -1)
layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
+9 -7
View File
@@ -1,15 +1,17 @@
![header](./header.png)
![Animation](./Screenshots/folding-cell.gif)
<img src="https://github.com/Ramotion/folding-cell/blob/master/Screenshots/foldingCell.gif" width="600" height="450" /></a>
<br><br/>
# FoldingCell
[![CocoaPods](https://img.shields.io/cocoapods/p/FoldingCell.svg)](https://cocoapods.org/pods/FoldingCell)
[![CocoaPods](https://img.shields.io/cocoapods/v/FoldingCell.svg)](http://cocoapods.org/pods/FoldingCell)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Ramotion/folding-cell)
[![Twitter](https://img.shields.io/badge/Twitter-@Ramotion-blue.svg?style=flat)](http://twitter.com/Ramotion)
[![Travis](https://img.shields.io/travis/Ramotion/folding-cell.svg)](https://travis-ci.org/Ramotion/folding-cell)
[![codebeat badge](https://codebeat.co/badges/6f67da5d-c416-4bac-9fb7-c2dc938feedc)](https://codebeat.co/projects/github-com-ramotion-folding-cell)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Swift 4.0](https://img.shields.io/badge/Swift-4.0-green.svg?style=flat)](https://developer.apple.com/swift/)
[![Analytics](https://ga-beacon.appspot.com/UA-84973210-1/ramotion/folding-cell)](https://github.com/igrigorik/ga-beacon)
[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/Ramotion)
# Check this library on other platforms:
<a href="https://github.com/Ramotion/folding-cell-android">
@@ -18,7 +20,7 @@
**Looking for developers for your project?**<br>
This project is maintained by Ramotion, Inc. We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
<a href="https://ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=folding-cell-contact-us/#Get_in_Touch">
<a href="https://dev.ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=folding-cell-contact-us">
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a> <br>
@@ -72,7 +74,6 @@ Your result should be something like this picture:
![1.3](https://raw.githubusercontent.com/Ramotion/folding-cell/master/Tutorial-resources/1.3.png)
[Demonstration adding constraints for foregroundView, containerView](https://vimeo.com/154954299)
4) Set ``` @IBInspectable var itemCount: NSInteger ``` property is a count of folding (it IBInspectable you can set in storyboard). range 2 or greater. Default value is 2
@@ -168,10 +169,11 @@ Try this UI component and more like this in our iOS app. Contact us if intereste
<a href="https://itunes.apple.com/app/apple-store/id1182360240?pt=550053&ct=folding-cell&mt=8" >
<img src="https://github.com/ramotion/gliding-collection/raw/master/app_store@2x.png" width="117" height="34"></a>
<a href="https://ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=folding-cell-contact-us/#Get_in_Touch">
<a href="https://dev.ramotion.com/?utm_source=gthb&utm_medium=special&utm_campaign=folding-cell-contact-us">
<img src="https://github.com/ramotion/gliding-collection/raw/master/contact_our_team@2x.png" width="187" height="34"></a>
<br>
<br>
Follow us for the latest updates<br>[![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=https://github.com/ramotion/folding-cell)
[![Twitter Follow](https://img.shields.io/twitter/follow/ramotion.svg?style=social)](https://twitter.com/ramotion)
Follow us for the latest updates<br>
<a href="https://goo.gl/rPFpid" >
<img src="https://i.imgur.com/ziSqeSo.png/" width="156" height="28"></a>
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB