swift 按顺序排列数组中的每个元素

zhte4eai  于 5个月前  发布在  Swift
关注(0)|答案(2)|浏览(41)

我试图在几秒钟内显示文本数组的每个成员。我编写的代码在整个时间内显示最后一个成员。如何解决这个问题?

import SwiftUI

class ViewController: UIViewController {

    var connectedView: UIView?
    var emotionView: UIView?
    var labelsButton = UIButton(type: .roundedRect)
              
    let labels = ["Apple", "Baby", "Cat", "Dog", "Evening", "Friend", "Go", "Happy", "Independent", "Joyful"]
   
    override func viewDidLoad() {
        super.viewDidLoad()
        layoutForConnected()
    }
  
    @objc func didTouchlabelButton(_ sender: UIButton?) {
        sender?.setTitle("Labels", for: .normal)
        layoutForCharacter()
    }
          
    func layoutForConnected() {
        if connectedView == nil {
            connectedView = UIView(frame: view.bounds)
            connectedView?.backgroundColor = UIColor.white
            
            labelsButton.frame = CGRect(x: 70, y: 475, width: 180, height: 60)
            labelsButton.setTitle("Labels", for: .normal)
            labelsButton.addTarget(self,action:
                                        #selector(didTouchlabelButton),for: .touchUpInside)
            labelsButton.tintColor = UIColor.black
            labelsButton.backgroundColor = UIColor.init(hue: 0.563, saturation: 1.0, brightness: 0.93, alpha: 1.0)
            labelsButton.layer.cornerRadius = 20
            connectedView?.addSubview(labelsButton)
        }
        
        if let connectedView = connectedView {
            self.view.addSubview(connectedView)
        }
    }
    
    var displayTime = 5.0
    var index = 0
       
    func layoutForCharacter() {
                
        // set up frame and background color
        emotionView = UIView(frame: view.bounds)
        emotionView?.backgroundColor = UIColor.init(hue: 0.563, saturation: 1.0, brightness: 0.93, alpha: 1.0)
        
        let labelLabel = UILabel(frame: CGRect(x: 0, y: 400 , width: view.frame.size.width, height: 20))
        labelLabel.textAlignment = .center
        
        // Display each label for displayTime seconds
               index = 0
        
        view?.addSubview(labelLabel)
        labelLabel.text = labels[index]
        
        while index < 9
        {
          labelLabel.text = labels[index] // Displays "Joyful", i.e. index = 9
            
            DispatchQueue.main.asyncAfter(deadline: .now() + displayTime * Double(index))
            {  [self] in
                labelLabel.text = labels[index]
            }
            self.index += 1
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + displayTime * Double(index))
        {  [self] in
            self.layoutForConnected()
        }
    }
}

字符串
我已经改变了DispatchQueue.main.asyncAfter的位置,但这并没有纠正问题。

fbcarpbf

fbcarpbf1#

我想你可以用递归的方式重写它。它很容易阅读。

func layoutForCharacter() {
    ...
    recursiveShowUpEmotion(label: labelLabel, index: index)
}

private func recursiveShowUpEmotion(label: UILabel, index: Int) {
    guard index < 9 else {
        layoutForConnected()
        return
    }
    label.text = labels[index]
    
    DispatchQueue.main.asyncAfter(deadline: .now() + displayTime) {
        self.recursiveShowUpEmotion(label: label, index: index + 1)
    }
}

字符串
在你的场景中,你延迟了label.text赋值,而不是index。所以当循环执行时,index将立即达到9。然后在DispatchQueue中的index 9处执行10次。这就是为什么你总是看到Joyful

3zwjbxry

3zwjbxry2#

谢谢大家。我不能让递归方法工作,但这可能是我如何应用它的。
在Foti Dim的帮助下,我开发了以下内容:

var displayTime = 5.0
var chosenLabel = 0

func layoutForCharacter() {
    // set up frame and background color
    emotionView = UIView(frame: view.bounds)
    emotionView?.backgroundColor = UIColor.init(hue: 0.563, saturation: 1.0, brightness: 0.93, alpha: 1.0)
    
    let labelLabel = UILabel(frame: CGRect(x: 0, y: 400 , width: view.frame.size.width, height: 20))
    labelLabel.textAlignment = .center
    
    // Display each label for displayTime seconds
    chosenLabel = 0
    
    view?.addSubview(labelLabel)
    
    // Use a timer to display each label
    var chosenLabel = 0
    Timer.scheduledTimer(withTimeInterval: displayTime, repeats: true) { [self] timer in
        // labelLabel.text = String (chosenLabel)
        labelLabel.text = self.labels[chosenLabel]
        
        chosenLabel += 1
        if chosenLabel == self.labels.count {
            timer.invalidate()
            DispatchQueue.main.asyncAfter(deadline: .now() + self.displayTime) {
                self.layoutForConnected()
            }
        }
    }
}

字符串

相关问题