提问人:MarkB 提问时间:11/17/2023 最后编辑:HangarRashMarkB 更新时间:11/17/2023 访问量:41
按顺序显示数组中的每个元素
Displaying each element in an array in sequence
问:
我正在尝试显示文本数组的每个成员几秒钟。我编写的代码始终显示最后一个成员。这应该如何解决?
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
答:
0赞
son
11/17/2023
#1
我认为你可以用递归的方式重写它。它很容易阅读。
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 赋值,而不是索引赋值。因此,当循环执行时,将立即达到 9。然后在索引 9 处内 10 次。这就是为什么你总是看到.index
DispatchQueue
Joyful
评论
1赞
HangarRash
11/17/2023
没有理由成为财产。使其成为此函数的参数。index
0赞
MarkB
12/16/2023
#2
谢谢大家。我无法让提议的递归方法起作用,但这可能就是我应用它的方式。
在 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()
}
}
}
}
评论
0赞
HangarRash
12/16/2023
与原始代码一样,每次调用 时都会不断添加新标签。layoutForCharacter
评论
SwiftUI
UIKit
labelLabel.text = labels[index]
while