Swift中while循环完成后触发ViewController跳转异常问题求助
别慌!新手常见的逻辑问题,我帮你搞定~
嘿,作为Swift新手碰到这种逻辑bug太正常了!先理清楚你的核心需求:
- 点击屏幕时从
answerSet数组里随机不重复弹出字符串 - 等所有字符串都展示完之后,再点击就触发
toEnd的segue跳转到下一页
现在问题是还没展示完所有内容就提前跳转了,大概率是你判断「是否展示完毕」的逻辑出了问题,我给你一步步拆解修复思路:
先排查你的核心逻辑坑
你说用了while循环实现随机不重复,那很大可能是你在循环里的结束判断写错了——比如误把「还剩最后一个元素」当成了「已经展示完所有元素」,导致还没展示最后一个就跳转了。
举个常见的错误例子:
// ❌ 错误写法:数组还剩1个元素时就跳转,这个元素根本没展示给用户 if answerSet.count == 1 { performSegue(withIdentifier: "toEnd", sender: self) }
正确的逻辑应该是:只有当所有元素都已经被展示过之后,再点击才触发跳转。
给你两种靠谱的实现方案
方案1:用「已使用数组」跟踪展示记录
适合需要严格保留原数组的场景:
// 把这些定义在ViewController类里 var usedAnswers: [String] = [] let answerSet: [String] = ["答案A", "答案B", "答案C", "答案D"] // 你的原数组 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) // 先检查是否还有未展示的内容 if usedAnswers.count < answerSet.count { // 随机选一个没展示过的元素 var randomIndex: Int repeat { randomIndex = Int.random(in: 0..<answerSet.count) } while usedAnswers.contains(answerSet[randomIndex]) // 展示这个字符串(比如赋值给你的UILabel) yourAnswerLabel.text = answerSet[randomIndex] // 把用过的元素加入已使用数组 usedAnswers.append(answerSet[randomIndex]) } else { // 所有内容都展示完了,触发跳转 performSegue(withIdentifier: "toEnd", sender: self) } }
方案2:用打乱数组的方式(更简洁高效)
如果不需要保留原数组的顺序,这种写法更不容易出错:
// 定义在ViewController类里 var shuffledAnswers: [String]! override func viewDidLoad() { super.viewDidLoad() // 页面加载时把原数组打乱 shuffledAnswers = answerSet.shuffled() } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) if !shuffledAnswers.isEmpty { // 取出第一个元素展示 let nextAnswer = shuffledAnswers.removeFirst() yourAnswerLabel.text = nextAnswer } else { // 数组空了=所有内容都展示完,触发跳转 performSegue(withIdentifier: "toEnd", sender: self) } }
关键注意点
- 绝对不要在循环里提前触发segue,一定要等所有元素都已经展示给用户之后,再在点击时判断是否跳转
- 如果你的原代码是直接修改
answerSet(比如remove(at: index)),一定要注意数组长度变化带来的计数问题——判断answerSet.isEmpty才是准确的结束条件 - 测试的时候可以给每个字符串加编号(比如「答案1」「答案2」),这样能清楚看到是否所有元素都展示过了再跳转
内容的提问来源于stack exchange,提问作者Pablo
相关产品推荐
相关产品推荐

