[英]Depth Page transform on iOS
我正在嘗試創建一個類似於POP菜單的Facebook菜單滑動動畫或類似於InShorts App的動畫。 Android文檔涵蓋了這個..但是在iOS中找不到任何提示。
我試過的是將細胞轉化為
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
UIView.animateWithDuration(0.1, animations: { () -> Void in
cell.transform = CGAffineTransformMakeScale(0.8, 0.8)
})
}
但這並沒有像預期的那樣工作。谷歌搜索我發現這正是我想要達到的目標。 但它在UIView
。 我認為如果我們在UITableViewCell
制作動畫最合適嗎? 我真的很感激有人願意幫助解決這個問題。 這是我正在開發的入門項目
使用UICollectionView
可以獲得此效果。這是UICollectionViewFlowLayout
類。
class UltravisualLayout: UICollectionViewLayout {
private var contentWidth:CGFloat!
private var contentHeight:CGFloat!
private var yOffset:CGFloat = 0
var maxAlpha:CGFloat = 1
var minAlpha:CGFloat = 0
var widthOffset:CGFloat = 35
var heightOffset:CGFloat = 35
private var cache = [UICollectionViewLayoutAttributes]()
private var itemWidth:CGFloat{
return (collectionView?.bounds.width)!
}
private var itemHeight:CGFloat{
return (collectionView?.bounds.height)!
}
private var collectionViewHeight:CGFloat{
return (collectionView?.bounds.height)!
}
private var numberOfItems:Int{
return (collectionView?.numberOfItemsInSection(0))!
}
private var dragOffset:CGFloat{
return (collectionView?.bounds.height)!
}
private var currentItemIndex:Int{
return max(0, Int(collectionView!.contentOffset.y / collectionViewHeight))
}
var nextItemBecomeCurrentPercentage:CGFloat{
return (collectionView!.contentOffset.y / (collectionViewHeight)) - CGFloat(currentItemIndex)
}
override func prepareLayout() {
cache.removeAll(keepCapacity: false)
yOffset = 0
for item in 0 ..< numberOfItems{
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let attribute = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
attribute.zIndex = -indexPath.row
if (indexPath.item == currentItemIndex+1) && (indexPath.item < numberOfItems){
attribute.alpha = minAlpha + max((maxAlpha-minAlpha) * nextItemBecomeCurrentPercentage, 0)
let width = itemWidth - widthOffset + (widthOffset * nextItemBecomeCurrentPercentage)
let height = itemHeight - heightOffset + (heightOffset * nextItemBecomeCurrentPercentage)
let deltaWidth = width/itemWidth
let deltaHeight = height/itemHeight
attribute.frame = CGRectMake(0, yOffset, itemWidth, itemHeight)
attribute.transform = CGAffineTransformMakeScale(deltaWidth, deltaHeight)
attribute.center.y = (collectionView?.center.y)! + (collectionView?.contentOffset.y)!
attribute.center.x = (collectionView?.center.x)! + (collectionView?.contentOffset.x)!
yOffset += collectionViewHeight
}else{
attribute.frame = CGRectMake(0, yOffset, itemWidth, itemHeight)
attribute.center.y = (collectionView?.center.y)! + yOffset
attribute.center.x = (collectionView?.center.x)!
yOffset += collectionViewHeight
}
cache.append(attribute)
}
}
//Return the size of ContentView
override func collectionViewContentSize() -> CGSize {
contentWidth = (collectionView?.bounds.width)!
contentHeight = CGFloat(numberOfItems) * (collectionView?.bounds.height)!
return CGSizeMake(contentWidth, contentHeight)
}
//Return Attributes whose frame lies in the Visible Rect
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attribute in cache{
if CGRectIntersectsRect(attribute.frame, rect){
layoutAttributes.append(attribute)
}
}
return layoutAttributes
}
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
let itemIndex = round(proposedContentOffset.y / (dragOffset))
let yOffset = itemIndex * (collectionView?.bounds.height)!
return CGPoint(x: 0, y: yOffset)
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
// Logic that calculates the UICollectionViewLayoutAttributes of the item
// and returns the UICollectionViewLayoutAttributes
return UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
}
}
這是演示項目鏈接 ......
非常感謝本教程 。
如果您想要InShorts視頻正在做什么,我建議使用視圖控制器轉換 。 一篇有用的文章就在這里 。
您要實現的完整示例代碼如下所示。 為了簡潔起見,我在app委托中實現了所有這些,但你絕對應該將它分解為單獨的類。
視頻: 這里
更新的代碼
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning {
var window: UIWindow?
var percentManager: UIPercentDrivenInteractiveTransition?
/**
Keep track of which way the animation is going
*/
var isPopping = false
/**
The index of the view controller that is currently presented.
*/
var index: Int {
get {
guard let lastVC = navController.viewControllers.last as? ViewController else { return NSNotFound }
return lastVC.index
}
}
/**
Acting as a very basic data source.
- Note: When this value is set the navigation stack is reset and the first VC is created
*/
var count: Int = 0 {
didSet {
guard count > 0 else { return }
// load the first view controller
navController.setViewControllers([ViewController(index: 0)], animated: true)
}
}
lazy var navController: UINavigationController = {
// create a navigation controller and hide it's nav bar
let navController = UINavigationController()
navController.navigationBar.hidden = true
return navController
}()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// add the nav controller (and it's first view controller) to the window
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = navController
window?.makeKeyAndVisible()
// add a pan recognizer to the nav controller
let panRecognizer = UIPanGestureRecognizer(target: self, action: Selector("didPan:"))
navController.view.addGestureRecognizer(panRecognizer)
navController.delegate = self
// update the 'data source'
count = 5
return true
}
internal func didPan(recognizer: UIPanGestureRecognizer) {
guard let view = recognizer.view else { assertionFailure("no view"); return }
switch (recognizer.state) {
case .Began:
// detect if it is an upward swipe
if recognizer.velocityInView(view).y < 0 {
// don't go out of bounds
guard index + 1 < count else { recognizer.enabled = false; recognizer.enabled = true; return }
isPopping = false
// create the percentManager and start pushing the next view controller
percentManager = UIPercentDrivenInteractiveTransition()
navController.pushViewController(ViewController(index: index+1), animated: true)
}
// detect if it is a downward swipe
else if recognizer.velocityInView(view).y > 0 {
// don't go out of bounds
guard index - 1 >= 0 else { recognizer.enabled = false; recognizer.enabled = true; return }
isPopping = true
// create the percentManager and start popping the current view controller
percentManager = UIPercentDrivenInteractiveTransition()
navController.popViewControllerAnimated(true)
}
case .Changed:
// update the percent manager
let translation = recognizer.translationInView(view)
let percentOffset = translation.y/CGRectGetHeight(view.bounds) * (isPopping ? 1 : -1)
percentManager?.updateInteractiveTransition(percentOffset)
case .Ended:
// give the percent manager it's final instruction before niling it
if isPopping {
if recognizer.velocityInView(view).y > 0 {
percentManager?.finishInteractiveTransition()
} else {
percentManager?.cancelInteractiveTransition()
}
} else {
if recognizer.velocityInView(view).y < 0 {
percentManager?.finishInteractiveTransition()
} else {
percentManager?.cancelInteractiveTransition()
}
}
percentManager = nil
default:
break
}
}
// MARK: UINavigationControllerDelegate
func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return percentManager
}
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
// MARK: UIViewControllerAnimatedTransitioning
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.4
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
guard let newVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as? ViewController else { assertionFailure("no new view controller"); return }
guard let oldVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as? ViewController else { assertionFailure("no existing view controller"); return }
let scaleTransform = CGAffineTransformMakeScale(0.9, 0.9)
let yOffsetTransform = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(oldVC.view.frame))
let isPopping = newVC.index < oldVC.index
let animationBlock: Void -> Void
if isPopping == true {
// place the previous vc at the top of the screen
newVC.view.transform = yOffsetTransform
animationBlock = {
oldVC.view.transform = scaleTransform
newVC.view.transform = CGAffineTransformIdentity
}
// add the views onto the transition view controller
transitionContext.containerView()?.addSubview(oldVC.view)
transitionContext.containerView()?.addSubview(newVC.view)
} else {
// scale the new view a bit smaller
newVC.view.transform = scaleTransform
// slide the old view controller up and scale the new view controller back to 100%
animationBlock = {
oldVC.view.transform = yOffsetTransform
newVC.view.transform = CGAffineTransformIdentity
}
// add the views onto the transition view controller
transitionContext.containerView()?.addSubview(newVC.view)
transitionContext.containerView()?.addSubview(oldVC.view)
}
// perform the animation
UIView.animateWithDuration(self.transitionDuration(transitionContext), animations: animationBlock, completion: { finished in
// cleanup
oldVC.view.transform = CGAffineTransformIdentity
newVC.view.transform = CGAffineTransformIdentity
transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
})
}
}
class ViewController: UIViewController {
let index: Int
init(index: Int) {
self.index = index
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: CGFloat((arc4random()%255))/255.0, green: CGFloat((arc4random()%255))/255.0, blue: CGFloat((arc4random()%255))/255.0, alpha: 1)
view.layer.cornerRadius = 12
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
根據您的視頻,我整理出您想要做的動畫類型。 所以這次是我的方法
self.view
),並實現平移觸摸的3種狀態 此代碼具有簡單視圖,這些視圖會根據顏色數組上的顏色數更改其背景。 因此,在您的情況下,您可以創建自定義XIB視圖,而不是顏色,您可以添加自己的數據源。 :)
import UIKit
class StackedViewController: UIViewController {
var previousView: UIView! = nil
var currentView: UIView! = nil
var nextView: UIView! = nil
var currentIndex = 0
let colors: [UIColor] = [.redColor(), .greenColor(), .yellowColor(), .grayColor()]
var offset: CGFloat = CGFloat()
// MARK: - View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Set the offset
offset = 64.0
setupViews()
}
// MARK: - Setups
func setupViews() {
self.view.backgroundColor = .blackColor()
self.currentView = getCurrentView()
self.view.addSubview(currentView)
let pan = UIPanGestureRecognizer(target: self, action: "panAction:")
self.view.addGestureRecognizer(pan)
}
// MARK: - Actions
func panAction(gesture:UIPanGestureRecognizer){
let p = gesture.translationInView(self.view)
// Edge cases to disable panning when the view stack is finished
if p.y < 0 && getPreviousView() == nil || p.y > 0 && getNextView() == nil {
return
}
if gesture.state == .Began {
if let prev = getPreviousView() {
self.previousView = prev
self.view.addSubview(prev)
prev.frame = self.view.frame
prev.center = CGPointMake(self.view.bounds.width/2, self.view.bounds.height/2)
self.view.sendSubviewToBack(previousView)
}
if let next = getNextView() {
self.nextView = next
self.view.addSubview(next)
next.frame = CGRect(origin: CGPoint(x: 0, y: -self.view.bounds.height), size: self.view.frame.size)
}
} else if gesture.state == .Changed {
UIView.animateWithDuration(0.1, animations: { () -> Void in
if p.y < 0 {
self.previousView.hidden = false
self.currentView.center.y = self.view.bounds.height/2 + p.y
self.previousView.center.y = self.view.bounds.height/2
// Transforming ratio from 0-1 to 0.9-1
let ratio = (-p.y/CGRectGetHeight(self.view.bounds))
let lightRatio = 0.9 + (ratio/10)
// Apply transformation
self.apply3DDepthTransform(self.previousView, ratio: lightRatio)
} else if p.y > 0 {
self.currentView.center.y = self.view.bounds.height/2
let prevPosY = -self.view.bounds.height/2 + p.y
if prevPosY < self.view.bounds.height/2 {
self.nextView?.center.y = prevPosY
} else {
self.nextView?.center.y = self.view.bounds.height/2
}
// Transforming ratio from 0-1 to 0.9-1
let ratio = p.y/CGRectGetHeight(self.view.bounds)
let lightRatio = 1 - (ratio/10)
// Apply transformation
self.apply3DDepthTransform(self.currentView, ratio: lightRatio)
// Hide the background view when showing another because the edges of this will be shown due to transformation
if self.previousView != nil {
self.previousView.hidden = true
}
}
})
} else if gesture.state == .Ended {
UIView.animateWithDuration(0.5, delay: 0,
options: [.CurveEaseOut], animations: { () -> Void in
if p.y < -self.offset && self.previousView != nil {
// Showing previous item
self.currentView.center.y = -self.view.bounds.height/2
// Finish the whole transition
self.apply3DDepthTransform(self.previousView, ratio: 1)
} else if p.y > self.offset && self.nextView != nil {
// Showing next item
self.nextView?.center.y = self.view.bounds.height/2
// Finish the whole transition
self.apply3DDepthTransform(self.currentView, ratio: 0.9)
} else {
// The pan has not passed offset so just return to the main coordinates
self.previousView?.center.y = -self.view.bounds.height/2
self.currentView.center.y = self.view.bounds.height/2
}
}, completion: { (_) -> Void in
if p.y < -self.offset && self.previousView != nil {
self.currentView = self.getPreviousView()
self.currentIndex = (self.currentIndex > 0) ? self.currentIndex - 1 : self.currentIndex;
} else if p.y > self.offset && self.nextView != nil {
self.currentView = self.getNextView()
self.currentIndex = (self.currentIndex == self.colors.count - 1) ? self.currentIndex : self.currentIndex + 1;
}
// Remove all views and show the currentView
for view in self.view.subviews {
view.removeFromSuperview()
}
self.previousView = nil
self.nextView = nil
self.view.addSubview(self.currentView)
self.currentView.center = CGPointMake(self.view.bounds.width/2, self.view.bounds.height/2)
})
}
}
// MARK: - Helpers
func getCurrentView() -> UIView? {
let current = UIView(frame: self.view.frame)
current.backgroundColor = colors[currentIndex]
return current
}
func getNextView() -> UIView? {
if currentIndex >= colors.count - 1 {
return nil
}
let next = UIView(frame: self.view.frame)
next.backgroundColor = colors[currentIndex + 1]
return next
}
func getPreviousView() -> UIView? {
if currentIndex <= 0 {
return nil
}
let prev = UIView(frame: self.view.frame)
prev.backgroundColor = colors[currentIndex - 1]
return prev
}
// MARK: Animation
func apply3DDepthTransform(view: UIView, ratio: CGFloat) {
view.layer.transform = CATransform3DMakeScale(ratio, ratio, ratio)
view.alpha = 1 - ((1 - ratio)*10)
}
}
您只能在需要單元格的情況下執行此操作,而無需使用UIViewController
進行自定義轉換
解決方案包括:
scrollViewDidScroll:
它協調整個操作,因為一切都依賴於scrollingOffset
ViewController
上的Autolayout存在一些問題。 請清除現有約束,使用tableView填充視圖,然后從頂部 (非頂部布局指南 )將其設置為0px。 沒有更多的談話,代碼談論自己(它也有一些評論)
import UIKit
enum ViewControllerScrollDirection: Int {
case Up
case Down
case None
}
class ViewController: UIViewController {
@IBOutlet weak var menuTableView: UITableView!
var colors :[UIColor] = [UIColor.greenColor(),UIColor.grayColor(),UIColor.purpleColor(),UIColor.redColor()]
var presenterCell: UITableViewCell! = nil
var isBeingPresentedCell: UITableViewCell! = nil
var lastContentOffset: CGFloat = CGFloat()
var scrollDirection: ViewControllerScrollDirection = .None
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
menuTableView.dataSource = self
menuTableView.delegate = self
menuTableView.pagingEnabled = true
}
}
extension ViewController:UITableViewDataSource,UITableViewDelegate {
// MARK: - Delegation
// MARK: TableView Datasource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.contentView.backgroundColor = colors[indexPath.row]
cell.backgroundColor = UIColor.blackColor()
cell.contentView.layer.transform = CATransform3DIdentity
cell.selectionStyle = .None
return cell
}
// MARK: TableView Delegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return self.view.frame.size.height
}
// MARK: ScrollView Delegate
func scrollViewDidScroll(scrollView: UIScrollView) {
self.scrollDirection = getScrollDirection(scrollView)
// The cells in visible cells are ordered, so depending on scroll we set the one that we want to present
if self.scrollDirection == .Up {
self.presenterCell = menuTableView.visibleCells.last
self.isBeingPresentedCell = menuTableView.visibleCells.first
} else {
self.presenterCell = menuTableView.visibleCells.first
self.isBeingPresentedCell = menuTableView.visibleCells.last
}
// If we have the same cells or either of them is nil don't do anything
if (self.isBeingPresentedCell == nil || self.presenterCell == nil) {
return;
} else if (self.isBeingPresentedCell == self.presenterCell) {
return;
}
// Always animate the presenter cell to the identity (fixes the problem when changing direction on pan gesture)
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.presenterCell.contentView.layer.transform = CATransform3DIdentity;
})
// Get the indexPath
guard let indexPath = menuTableView.indexPathForCell(presenterCell) else {
return;
}
// Get the frame for that indexPath
let frame = menuTableView.rectForRowAtIndexPath(indexPath)
// Find how much vertical space is the isBeingPresented cell using on the frame and return always the positive value
var diffY = frame.origin.y - self.lastContentOffset
diffY = (diffY > 0) ? diffY : -diffY
// Find the ratio from 0-1 which corresponds on transformation from 0.8-1
var ratio = CGFloat(diffY/CGRectGetHeight(self.menuTableView.frame))
ratio = 0.8 + (ratio/5)
// Make the animation
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.isBeingPresentedCell.contentView.layer.transform = CATransform3DMakeScale(ratio, ratio, ratio)
})
}
// MARK: - Helpers
func getScrollDirection(scrollView: UIScrollView) -> ViewControllerScrollDirection {
let scrollDirection = (self.lastContentOffset > scrollView.contentOffset.y) ? ViewControllerScrollDirection.Down : ViewControllerScrollDirection.Up
self.lastContentOffset = scrollView.contentOffset.y;
return scrollDirection
}
}
希望它能滿足你的要求:)
使用facebook POP動畫用於拖放拖動視圖以休息動畫
private func resetViewPositionAndTransformations() {
let resetPositionAnimation = POPSpringAnimation(propertyNamed: kPOPLayerTranslationXY)
resetPositionAnimation.fromValue = NSValue(CGPoint: CGPoint(x: dragDistance.x, y: dragDistance.y))
resetPositionAnimation.toValue = NSValue(CGPoint: CGPointZero)
resetPositionAnimation.springBounciness = cardResetAnimationSpringBounciness
resetPositionAnimation.springSpeed = cardResetAnimationSpringSpeed
resetPositionAnimation.completionBlock = {
(_, _) in
self.layer.transform = CATransform3DIdentity
}
layer.pop_addAnimation(resetPositionAnimation, forKey: "resetPositionAnimation")
let resetRotationAnimation = POPBasicAnimation(propertyNamed: kPOPLayerRotation)
resetRotationAnimation.fromValue = POPLayerGetRotationZ(layer)
resetRotationAnimation.toValue = CGFloat(0.0)
resetRotationAnimation.duration = cardResetAnimationDuration
layer.pop_addAnimation(resetRotationAnimation, forKey: "resetRotationAnimation")
let overlayAlphaAnimation = POPBasicAnimation(propertyNamed: kPOPViewAlpha)
overlayAlphaAnimation.toValue = 0.0
overlayAlphaAnimation.duration = cardResetAnimationDuration
overlayAlphaAnimation.completionBlock = { _, _ in
}
overlayView?.pop_addAnimation(overlayAlphaAnimation, forKey: "resetOverlayAnimation")
let resetScaleAnimation = POPBasicAnimation(propertyNamed: kPOPLayerScaleXY)
resetScaleAnimation.toValue = NSValue(CGPoint: CGPoint(x: 1.0, y: 1.0))
resetScaleAnimation.duration = cardResetAnimationDuration
layer.pop_addAnimation(resetScaleAnimation, forKey: "resetScaleAnimation")
}
在我看來, UICollectionview
和UICollectionViewLayout
更適合這類事情。 UITableView
不會給你每個滾動變換,你需要做各種臟黑客。
如果你使用UICollectionview
,你要找的是-[UICollectionViewLayout layoutAttributesForElementsInRect:]
和-[UICollectionViewLayout shouldInvalidateLayoutForBoundsChange:]
,其他一切都是一些數學。
試試這個:你可以通過facebook / pop https://github.com/facebook/pop獲得更流暢的效果。 這段代碼只是為了給你一些想法,而不是經過多少測試。
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")
if cell?.contentView.viewWithTag(100) == nil
{
let view = UIView(frame: (cell?.contentView.bounds)!)
view.tag = 100
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
cell?.contentView.addSubview(view)
}
if cell!.contentView.viewWithTag(100) != nil
{
let view = cell!.contentView.viewWithTag(100)
view!.backgroundColor = colors[indexPath.row]
}
return cell!
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return self.view.frame.size.height - 20
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.contentView.viewWithTag(100) != nil
{
let view = cell.contentView.viewWithTag(100)
let basicAnimation = CABasicAnimation(keyPath: "transform.scale")
basicAnimation.toValue = NSNumber(float: 1)
basicAnimation.fromValue = NSNumber(float: 0.8)
basicAnimation.duration = 0.4
basicAnimation.removedOnCompletion = false
view!.layer.addAnimation(basicAnimation, forKey: "transform.scale")
}
// if tableView.cellForRowAtIndexPath(NSIndexPath(forRow: indexPath.row - 1, inSection: 0)) != nil
// {
// let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: indexPath.row - 1, inSection: 0))
// if cell!.contentView.viewWithTag(100) != nil
// {
// let view = cell!.contentView.viewWithTag(100)
// let basicAnimation = CABasicAnimation(keyPath: "transform.scale")
// basicAnimation.toValue = NSNumber(float: 0.8)
// basicAnimation.fromValue = NSNumber(float: 1)
// basicAnimation.duration = 0.4
// basicAnimation.removedOnCompletion = false
// view!.layer.addAnimation(basicAnimation, forKey: "transform.scale")
// }
// }
// if tableView.cellForRowAtIndexPath(NSIndexPath(forRow: indexPath.row + 1, inSection: 0)) != nil
// {
// let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: indexPath.row + 1, inSection: 0))
//
// if cell!.contentView.viewWithTag(100) != nil
// {
// let view = cell!.contentView.viewWithTag(100)
// let basicAnimation = CABasicAnimation(keyPath: "transform.scale")
// basicAnimation.toValue = NSNumber(float: 0.8)
// basicAnimation.fromValue = NSNumber(float: 1)
// basicAnimation.duration = 0.4
// basicAnimation.removedOnCompletion = false
// view!.layer.addAnimation(basicAnimation, forKey: "transform.scale")
// }
// }
// let scaleAnimation = POPDecayAnimation(propertyNamed: kPOPLayerScaleXY)
// scaleAnimation.fromValue = NSValue(CGSize: CGSize(width: 0.8, height: 0.8))
// scaleAnimation.toValue = NSValue(CGSize: CGSize(width: 1, height: 1))
// cell.contentView.layer.pop_addAnimation(scaleAnimation, forKey: "kPOPLayerScaleXY")
// UIView.animateWithDuration(0.1, animations: { () -> Void in
// cell.transform = CGAffineTransformMakeScale(0.8, 0.8)
// })
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.