SwiftUI ForEach循环嵌套If语句优化及Xcode报错问题咨询
解决方案
核心优化思路
你遇到的Xcode报错是因为SwiftUI的ViewBuilder需要同时推导多个条件分支的视图类型,视图结构越复杂编译期类型计算开销越大,超过阈值就会抛出该错误。优化方向分为两步:抽离重复的子视图、把零散的verse属性转换为可遍历的数组,完全消除重复的if判断。
步骤1:抽离通用的节视图
把重复的verse行视图抽成独立的VerseRow子视图,减少重复代码:
struct VerseRow: View { /// 节数 let number: Int /// 歌词内容 let content: String /// 是否显示节数图标 let showNumber: Bool /// 字体名称 let fontName: String /// 字体大小 let fontSize: CGFloat var body: some View { HStack { if showNumber { Image(systemName: "\(number).circle.fill") .font(.title2) .foregroundColor(.red) } Text(content) .font(.custom(fontName, size: fontSize)) Spacer() } } }
步骤2:给Lyric扩展可遍历的节数组
给Lyric模型添加扩展,把零散的verse2~verse5属性整合为带序号的数组,不需要手动逐个判空:
extension Lyric { /// 整理好的带序号非空节列表 var validVerses: [(number: Int, content: String)] { var list = [(Int, String)]() if let verse2 = verse2 { list.append((2, verse2)) } if let verse3 = verse3 { list.append((3, verse3)) } if let verse4 = verse4 { list.append((4, verse4)) } if let verse5 = verse5 { list.append((5, verse5)) } return list } }
步骤3:改造原Home视图的循环逻辑
替换原来的4个重复if判断,用ForEach遍历整理好的节数组即可:
import SwiftUI struct Home: View { var lyrics: [Lyric] = LyricList.hymnLa @AppStorage("fontSizeIndex") var fontSizeIndex = 18 // 原写法Int("Medium")永远返回nil,建议根据实际需求调整存储逻辑 @AppStorage("fontIndex") var fontIndex: String = "" @AppStorage("showHVNumbers") var showHVNumbers: Bool = true // 注意:原代码用到的scrollToIndex未定义,需自行补全属性声明 var body: some View { ScrollView { ScrollViewReader { proxy in LazyVStack(spacing: 10) { ForEach (lyrics, id: \.id) { lyric in // 直接遍历非空节数组,无重复代码 ForEach(lyric.validVerses, id: \.number) { verse in VerseRow( number: verse.number, content: verse.content, showNumber: showHVNumbers, fontName: fontIndex, fontSize: CGFloat(fontSizeIndex) ) } } .foregroundColor(.primary) .padding(.horizontal, 10.0) .padding(.bottom) Divider() } .onChange(of: scrollToIndex, perform: { value in proxy.scrollTo(value, anchor: .top) }) } } } }
额外说明
修改后编译期不需要再推导多个独立的if分支视图类型,复杂度大幅降低,即可解决Expression was too complex to be solved in reasonable time报错。
内容的提问来源于stack exchange,提问作者Lian
相关产品推荐
相关产品推荐

