SwiftUI中字符串数组按日随机排序出现编译错误求助
问题原因
两处编译报错均为基础写法错误,同时原代码还存在逻辑缺陷无法实现按自然日固定排序的需求:
- 报错1
Cannot convert value of type '[String]' to expected argument type 'Range<Int>':ForEach直接遍历集合时,要么集合元素遵循Identifiable协议,要么显式指定元素id的keypath。原生String未遵循Identifiable,编译器无法匹配数组遍历的初始化方法,转而匹配接收整数区间的初始化方法,最终抛出类型不匹配错误。 - 报错2
Initializer 'init(_:)' requires that 'Int.Words' conform to 'StringProtocol':ForEach闭包中拿到的word本身就是遍历得到的单个字符串元素,你错误写成了word.words,String不存在words属性,编译器类型推断失败,误匹配到无关类型触发报错。 - 逻辑缺陷1:
isNewDay()返回值逻辑完全写反,存储日期和当前日期相等时属于同一天,不需要重新打乱;日期不等才是跨天需要重新排序。 - 逻辑缺陷2:直接在ForEach参数位置调用
shuffled()会在每次视图刷新时重新生成随机顺序,哪怕同一天内只要视图重绘单词顺序就会变化,根本无法实现按自然日固定随机排序的效果。
修正后代码
struct TestView: View { let words: [String] = [ "Hello", "Hola", "Ciao", ] var sortedWordsForDay: [String] { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MM/dd/yyyy" let todayStr = dateFormatter.string(from: Date()) let defaults = UserDefaults.standard // 检查是否是同一天且有已存储的排序结果 if let lastDate = defaults.string(forKey: "lastDate"), lastDate == todayStr, let savedList = defaults.stringArray(forKey: "dailyShuffledWords") { return savedList } // 跨天/首次启动:生成新的随机排序,持久化存储 let newShuffledList = words.shuffled() defaults.set(todayStr, forKey: "lastDate") defaults.set(newShuffledList, forKey: "dailyShuffledWords") return newShuffledList } var body: some View { ZStack { ForEach(sortedWordsForDay, id: \.self) { word in Text(word) .foregroundColor(.white) .fontWeight(.bold) .font(.title2) .multilineTextAlignment(.center) .padding(.horizontal, 15) .padding(.top, 1) } } } }
核心修改点
- ForEach遍历字符串数组时显式传入
id: \.self,明确元素唯一标识规则,解决第一个类型报错。 - 删除
word后多余的.words后缀,直接传入字符串本身给Text,解决第二个类型报错。 - 移除写反逻辑的
isNewDay方法,将每日排序逻辑整合为计算属性,把当日打乱后的数组持久化到本地,确保同一天内排序固定,跨天自动重新生成随机顺序。 - 避免在视图构建参数位置直接调用
shuffled(),防止视图刷新触发不必要的顺序变动。
内容的提问来源于stack exchange,提问作者user17136166
相关产品推荐
相关产品推荐

