代码之家  ›  专栏  ›  技术社区  ›  user8822312

swift:递归动画

  •  1
  • user8822312  · 技术社区  · 7 年前

    在我的应用程序中,我想制作一个字符串数组的动画,给用户一些指示。我的期望是第一个字符串淡入,保持数秒,然后淡出,然后从数组中删除第一个字符串,然后显示下一个字符串,依此类推,直到数组变空。我的实现有点问题,但很难调试(似乎程序不会逐行执行),下面是我的代码:

    var text = [Text.text1, Text.text2]
    @IBOutlet weak var paragraph: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        paragraph.alpha = 0
        showText(text: text)
    }
    
    private func showText(text: [String]) {
        if text.first == nil {
            return
        } else {
            paragraph.text = text.first
            UIView.animate(withDuration: 1.5, delay: 1.5, options: .curveEaseInOut, animations: {
                self.paragraph.alpha = 1
            }, completion: { (_) in
                UIView.animate(withDuration: 1.5, delay: 0.5, options: .curveEaseInOut, animations: {
                    self.paragraph.alpha = 0
                }, completion: { (_) in
                    self.text.remove(at: 0)
                    self.showText(text: text)
                })
            })
        }
    }
    

    问题是第一个字符串显示了三次,然后我得到了一个索引超出范围的错误。当我尝试设置断点并单击“跳过”时,它将跳过动画和完成块,并且我不知道如何调试以块为参数的函数。而且即使我有

    paragraph.text = text.first
    

    第一轮之后, paragraph.text 已经是第二个字符串,但仍然显示第一个字符串。 类似地,我的终止条件似乎不起作用:在两次迭代之后,我注意到 self.text 数组已变为0,但函数未返回,它转到其他。。。

    if text.count == 0 {
                return
            } else { ... }
    

    我是个新手,不知道如何调试块。。。

    1 回复  |  直到 7 年前
        1
  •  1
  •   rmaddy    7 年前

    问题很微妙,都在第二个完成块中。您有:

    self.text.remove(at: 0)
    self.showText(text: text)
    

    您更新了 text 但你要通过当地 文本 未更改的参数。

    将第二行更改为通过 self.text 而不仅仅是 文本 .

    但是引用 自己文本 在…内 showText 否定甚至需要有 文本 参数要么写入 显示文本 仅使用 文本 类的属性或更好的属性,仅引用 文本 参数后者的优点是不修改属性。

    要实现后一个选项,请将第二个完成块中的两行更改为:

    自己文本删除(在:0处)
    自己showText(文本:text)
    

    只是:

    self.showText(text: Array(text[1...]))