在Swift中逐行淡入UITableViewCell

8

我刚开始学习Swift,我想创建一个UITableView,并让单元格逐个动态出现。我该怎么做呢?如果新出现的单元格不在屏幕上(隐藏在表格下面),当每个单元格出现时,我该如何将表格向上移动?

    var tableData1: [String] = ["1", "2", "3", "4", "5", "6", "7"]

     override func viewWillAppear(animated: Bool) {
           tableView.scrollEnabled=false
    tableView.alpha=0.0
            NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(3), target: self, selector: "animateTable", userInfo: nil, repeats: false)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.tableData1.count
    }

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell     {

        let cell:TblCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! TblCell
        cell.lblCarName.textAlignment = NSTextAlignment.Justified;
return cell
}

func animateTable() {

//what should be the code?//
}
6个回答

12

步骤一

在你的cellForRowAtIndexPath方法中初始化cell时,可以像这样隐藏它:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell     {
    let cell: TblCell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TblCell
    cell.continueLabel.textAlignment = .justified
    cell.contentView.alpha = 0
    return cell
}

步骤二

让我们制作淡入淡出动画。 UITableViewDelegate有一个willDisplayCell方法,可以检测当您滚动到顶部或底部时,第一个单元格将显示在窗口中。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    UIView.animate(withDuration: 0.8, animations: {
        cell.contentView.alpha = 1
    })   
}

您的淡入淡出动画正在进行中。最重要的事情是,您不能直接在运行时设置单元格的透明度,因为iOS会将单元格作为UITableView的一部分进行一些特殊的内部处理,并忽略您的设置。因此,如果您设置了单元格的contentView,一切都会很好。


我尝试了这个代码,它可以工作,但我想要稍微不同的行为。你的代码会同时淡化所有行。我只想让tableView的每一行(底部行)逐渐消失。我该如何重复使用你的代码来实现这一点?另外,作为替代方案,我是否可以在2秒后删除底部行?谢谢。 - Edison

4
在UITableView中,当行进入你的“视野范围”时,它们会自动为你准备好。我假设你最初无法滚动tableView,所以我们需要通过编程方式滚动它,使行随着滚动逐渐出现。我们如何做到这一点?实际上,UITableView有一个方法可以让我们滚动到特定的行:
scrollToRowAtIndexPath(indexPath : NSIndexPath, atScrollPosition : UITableViewScrollPosition, animated : Bool);

我太累了,没力气写代码,所以我来试着解释一下。首先,在每个单元格中,当它们被加载时(cellForRowAtIndexPath),将 alpha 值设置为 0。 然后假设我们的屏幕适合前5行。您要依次使用 UIView.animateWithDuration 动画它们的 alpha 值,直到第五行(索引为4),然后使用 NSIndexPath 将 scrollToRowAtIndexPath 传递给5、6,… 直到剩余的行(使用 scrollPosition = .Bottom)。对于每个行,您需要在它们被加载时进行动画处理。只需记得在这些交互之间放点时间(先动画,运行 NSTimer 到第二个,依此类推)。当然,boolean 变量 animated 应该是 true。


谢谢!我已经将 alpha 设置为 0 了。我不确定的是如何让单元格一个接一个地出现?它们同时出现吗?我该如何控制或分配每个单元格? - Clarence
你实现的方法"cellForRowAtIndexPath"可以被调用来获取特定行的单元格。要使它们逐个出现,您可以使用NSTime.scheduledTimerWithTimeInterval进行调用。例如,为第一行传递1,为第二行传递2,为第三行传递3。 - Pietro Pepe

3
为了逐个显示每个可见单元格,您可以通过调整 alpha 和 duration 值来实现。
extension UITableView {

    func fadeVisibleCells() {

        var delayDuration: TimeInterval = 0.0

        for cell in visibleCells {

            cell.alpha = 0.0

            UIView.animate(withDuration: delayDuration) {
                cell.alpha = 1.0
            }

            delayCounter += 0.30
        }
    }
}

2

下面是一些可以帮助你入门的代码。在我的COBezierTableView中,我继承了UITableView并重写了layoutSubviews方法。在这里,您可以根据视图中单元格的相对位置来操作它们。在此示例中,我让它们在底部逐渐消失。

import UIKit

public class MyCustomTableView: UITableView {

    // MARK: - Layout

    public override func layoutSubviews() {
        super.layoutSubviews()

        let indexpaths = indexPathsForVisibleRows!
        let totalVisibleCells = indexpaths.count - 1
        if totalVisibleCells <= 0 { return }

        for index in 0...totalVisibleCells {
            let indexPath = indexpaths[index] 
            if let cell = cellForRowAtIndexPath(indexPath) {
                if let superView = superview {
                    let point = convertPoint(cell.frame.origin, toView:superView)
                    let pointScale = point.y / CGFloat(superView.bounds.size.height)
                    cell.contentView.alpha = 1 - pointScale
                }
            }
        }
    }
}

2
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell .alpha = 1.0
         let transform = CATransform3DTranslate(CATransform3DIdentity, 0, 3000, 1200)
       //let transform = CATransform3DTranslate(CATransform3DIdentity, 250, 0, 1250)
     //let transform = CATransform3DTranslate(CATransform3DIdentity, 250, 1250, 0)
      // let transform = CATransform3DTranslate(CATransform3DIdentity, -250, 300, 120)


   cell.layer.transform = transform




    UIView.animate(withDuration: 1.0) {
        cell.alpha = 1.0
        cell.layer.transform = CATransform3DIdentity
        cell.layer.transform = CATransform3DIdentity
    }
}

1
请仅翻译文本内容:请在您的代码中添加一些关于逻辑的说明!这将非常有帮助! - Rizwan Atta

0

我认为这种方法将是一个很好的解决方案。

  • 将所有单元格alpha设置为0
  • 在tableView(_:,willDisplay:,forRowAt:)中对它们进行动画处理
  • 为每个indexPath.row设置延迟
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    cell.alpha = 0

    UIView.animate(withDuration: 0.5, delay: 0.05 * Double(indexPath.row), animations: {
        cell.alpha = 1
    })
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接