swiftui - 在 SwiftUI 中滚动时,许多项目列表崩溃,我该如何解决?
问题描述
我在 SwiftUI 中有一个简单的项目列表,如下所示:
ForEach((1...50), id: \.self) {
Text("\($0)….........")
Text("\($0)….........")
Text("\($0)….........")
Text("\($0)….........")
}
我在使用更复杂的视图时遇到了同样的问题,但我在这里只用一个文本视图对其进行了简化。它产生同样的问题
崩溃错误:
2021-02-13 21:03:07.124039+1100 rawateb[1696:71245] [ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke
2021-02-13 21:03:07.163944+1100 rawateb[1696:71245] XPC connection interrupted
Message from debugger: Terminated due to signal 9
那么,如何在不崩溃的情况下处理大量项目
更新
我的完整代码是
//
// CalendarView.swift
// rawateb
//
// Created by Hatim Hoho on 7/2/21.
//
import SwiftUI
import Combine
import QGrid
struct CalendarView: View {
//@ObservedObject var viewModel = CalendarViewModel()
@EnvironmentObject var settings: UserSettings
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
@State var saleries = [FutureSalery]()
var body: some View {
ScrollView {
VStack {
GeometryReader { geometry in
HStack{
Button(action: {
print("Button was tapped")
// add new future salery
self.addFutureSalery()
}) {
Image(systemName: "plus.circle")
.resizable()
.foregroundColor(.blue)
}
.padding()
.frame(width: 70, height: 70, alignment: .center)
Text("رواتب الأشهر القادمة")
.font(.title2)
.bold()
.multilineTextAlignment(.center)
.foregroundColor(Color("labelColor"))
Button(action: {
print("Button was tapped")
self.removeFutureSalery()
}) {
Image(systemName: "minus.circle")
.resizable()
.foregroundColor(.blue)
}
.padding()
.frame(width: 70, height: 70, alignment: .center)
}
.padding([.top, .bottom], 38)
.offset(y: geometry.frame(in: .global).minY > 38 ? -geometry.frame(in: .global).minY+38 : 0)
.frame(width: geometry.size.width)
.blur(radius: -geometry.frame(in: .global).minY * 0.38)
}
.frame(height: 150)
Spacer()
//List {
ForEach((1...50).reversed(), id: \.self) {
Text("\($0)….........")
Text("\($0)….........")
Text("\($0)….........")
Text("\($0)….........")
}
// }
// QGrid(self.saleries, columns: 2) { salery in
// SaleryCellItem2(salery: salery)
// }
// .padding()
}
}
}
}
struct SaleryCellItem : View {
var salery: FutureSalery
var body: some View {
GeometryReader(content: { geometry in
HStack {
Text("\(salery.remainingDays)")
.frame(width: geometry.size.width / 3, height: geometry.size.height, alignment: .center)
VStack(alignment: .trailing) {
Text(salery.hjDateString)
Text(salery.acDateString)
}
.frame(width: geometry.size.width / 3 * 2, height: geometry.size.height, alignment: .trailing)
.offset(CGSize(width: -45, height: 0))
}
})
.frame(width: .none, height: 90, alignment: .center)
.background(Color("listItemBGColor"))
.cornerRadius(8)
}
}
struct SaleryCellItem2 : View {
var salery: FutureSalery
var body: some View {
VStack {
Text("\(salery.remainingDays)")
VStack(alignment: .trailing) {
Text(salery.hjDateString)
Text(salery.acDateString)
}
}
}
}
extension CalendarView {
func addFutureSalery() {
// get the last salery in list
var lastDate = Date()
if (saleries.count > 0) {
lastDate = saleries.last!.dateObject
}
var dayOfSalery = 1
switch settings.organizationType {
case SaleryOrgType.gov.rawValue:
dayOfSalery = 27
case SaleryOrgType.privateSector.rawValue:
dayOfSalery = Int(UserDefaults.standard.double(forKey: "saleryDayIfPrivateSector"))
case SaleryOrgType.taqaod.rawValue:
dayOfSalery = 20
default:
dayOfSalery = 1
}
// if list is empty -> get the soonest salery from today date
// get the next salery after that salery
// append
var nearestDate = Date()
if (saleries.count > 0) {
nearestDate = lastDate.nextMonthDate(withDayNumber: dayOfSalery)
} else {
// first item
nearestDate = lastDate.nearestDate(withNumber: dayOfSalery)
}
self.saleries.append(FutureSalery(dateObject: nearestDate))
print("count \(self.saleries.count)")
}
func removeFutureSalery() {
if(self.saleries.count > 0) {
self.saleries.removeLast()
}
print("count \(self.saleries.count)")
}
}
struct DateItem: Identifiable {
var id = UUID()
var title:String
}
struct CalendarView_Previews: PreviewProvider {
static var previews: some View {
Group {
CalendarView()
.previewDevice(PreviewDevice(rawValue: "iPhone 11 Pro Max"))
.previewDisplayName("iPhone 11 Pro Max")
}
}
}
解决方案
感谢@Asperi 在评论中提供解决方案。
问题是几何阅读器。
GeometryReader 不应该在 ScrollView 中,因为它会导致内存泄漏。
所以,每当我们有这样的代码
ScrollView {
VStack {
GeometryReader(content: { geometry in // <- look at this
...
应该改成这个
GeometryReader(content: { geometry in // <- look at this
ScrollView {
VStack {
...
谢谢
推荐阅读
- python-3.x - 如何从文件中收集数据作为实际数字而不是 Python 中的字符串?
- mysql - 如何为 mysql 查询内部连接查找表?
- caching - 错过率计算
- reactjs - 对于上下文所封装的页面组件,如何访问导航栏中的上下文状态?
- rust - 如何在不获取所有权的情况下为 Rust 切片命名?
- ios - 使用android studio在IOS模拟器中构建flutter应用程序时出错
- javascript - 减少计数,以便显示每个用户的所有供应商的计数
- python - ufunc true_divide 不能使用类型为 dtype('float64') 和 dtype('
我的代码有问题,我需要根据某些属性找到某个值。
xls = xlrd.open_workbook(filed, on_demand=True) for sheet_name in xls.sheet_names(): df = pd.read_excel(filed,sheet_name)
- python - Alpha Vantage“KeyError:'时间序列(每日)'”
- grails - Grails:运行插件时服务未注入控制器