一尘不染

iOS上的深度页面转换

swift

我正在尝试创建类似POP框架的Facebook Menu Slide Down Animation或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?我真的很感谢有人愿意帮助这个问题。是我正在从事的入门项目


阅读 237

收藏
2020-07-07

共1个答案

一尘不染

可以使用获得该效果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)
    }

}

这是演示项目链接

非常感谢本 教程

2020-07-07