NavigationStack加载Sheet时出现微卡顿问题求助
大家好,我最近在做SwiftUI项目时遇到了一个小困扰——当我通过sheet弹出包含NavigationStack的NewContactSheet视图时,总会出现轻微的卡顿感,流畅度不太理想。我把相关的代码都贴在下面了,想请教一下社区的大佬们,有没有人能帮忙排查下问题所在,或者给点优化的思路呀?
首先是触发Sheet的代码:
.sheet(isPresented: $newContactSheetTrigger) { NewContactSheet() .presentationDetents([.large]) }
然后是NewContactSheet的完整实现:
import SwiftUI import SwiftData import WidgetKit struct NewContactSheet: View { @Environment(\.dismiss) private var dismiss @State private var contactName = "" @State private var newDaysDue: Set<String> = [] @State private var favorite = false private let templatesHeight = UIScreen.main.bounds.height * 0.035 private let dayWidth = UIScreen.main.bounds.width * 0.1 private let weekdays: [String] = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] private let buttonBackground = Color(uiColor: .systemGroupedBackground) private let green85 = Color.green.opacity(0.85) private let green30 = Color.green.opacity(0.3) private let adaptiveBlack = Color("AdaptiveBlack") var body: some View { NavigationStack { Form { Section { TextField("Contact name", text: $contactName) HStack { Text("Templates:") .font(.footnote) .foregroundStyle(.secondary) ScrollView(.horizontal, showsIndicators: false) { LazyHStack { ForEach(NewContactTemplate.predefinedTemplates) { template in Button { if contactName == template.name { clearTemplate() } else { applyTemplate(template: template) } } label: { Text("\(template.name)") .padding(.horizontal) .font(.footnote) .frame(height: templatesHeight) .foregroundStyle(adaptiveBlack) } .background(buttonBackground, in: RoundedRectangle(cornerRadius: 10)) .buttonStyle(.borderless) } } } } .contentMargins(.horizontal, 0) } header: { Text("Name") } Section { HStack (alignment: .center) { Spacer() ForEach (weekdays, id: \.self) { day in let containsCheck = newDaysDue.contains(day) Button { if favorite { // activeAlert = .correctDaysSelector // showAlert = true } else { if containsCheck { newDaysDue.remove(day) } else { newDaysDue.insert(day) } } } label: { Text(day) .font(.caption) .frame(width: dayWidth, height: templatesHeight) .background( containsCheck ? RoundedRectangle(cornerRadius: 10) .fill(green85) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(.clear, lineWidth: 2) ) : RoundedRectangle(cornerRadius: 10) .fill(.clear) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(green30, lineWidth: 2) ) ) .foregroundStyle(favorite ? .gray : containsCheck ? .white : green85) } .buttonStyle(.plain) } Spacer() } HStack { Text("Presets:") .font(.footnote) .foregroundStyle(.secondary) ScrollView(.horizontal, showsIndicators: false) { LazyHStack { ForEach(NewContactDaysDue.predefinedTemplates) { template in Button { if newDaysDue.count == template.daycount { newDaysDue = [] } else { newDaysDue = template.daysDue } } label: { Text("\(template.name)") .padding(.horizontal) .font(.footnote) .frame(height: templatesHeight) .foregroundStyle(adaptiveBlack) } .buttonStyle(.borderless) .background(buttonBackground, in: RoundedRectangle(cornerRadius: 10)) } } } } .contentMargins(.horizontal, 0) } header: { Text("Meet") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } Section {} header: { Text("xxx") } } .scrollIndicators(.hidden) .toolbar { ToolbarItem(placement: .topBarLeading) { Button { dismiss() } label: { Text("Cancel") .foregroundStyle(.red) } } ToolbarItem(placement: .topBarTrailing) { Button { //implement save logic WidgetCenter.shared.reloadAllTimelines() dismiss() } label: { Text("Save") .foregroundStyle(.green) } } } .navigationTitle("New Contact") .navigationBarTitleDisplayMode(.inline) .navigationBarHidden(false) } } func applyTemplate(template: NewContactTemplate) { contactName = template.name } func clearTemplate() { contactName = "" } } #Preview { NewContactSheet() } struct NewContactTemplate: Identifiable { let id = UUID() let name: String let daysDue: Set<String> } extension NewContactTemplate { static let predefinedTemplates: [NewContactTemplate] = [ NewContactTemplate(name: "Test1", daysDue: ["Mon", "Tue", "Wed"]), NewContactTemplate(name: "Test2", daysDue: ["Tue", "Wed", "Fri"]), NewContactTemplate(name: "Test3", daysDue: ["Sat", "Sun", "Mon"]) ] } struct NewContactDaysDue: Identifiable { let id = UUID() let name: String let daysDue: Set<String> let daycount: Int } extension NewContactDaysDue { static let predefinedTemplates: [NewContactDaysDue] = [ NewContactDaysDue(name: "Daily", daysDue: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], daycount: 7), // 原代码此处有截断,保持原样未补充 ] }
我自己猜测是不是NavigationStack嵌套Form的结构在初始化时渲染压力有点大?或者有没有什么像延迟加载、预渲染之类的小技巧能缓解这个卡顿问题呀?麻烦大家帮忙看看啦,谢谢!
内容来源于stack exchange
相关产品推荐
相关产品推荐

