Ios 在获取数据期间,节中的行数索引超出范围
当尝试用我的tableview和进度条打开新控制器时,我的“索引超出范围”。 我从Firestore数据库获取数据,其想法是,当我点击“下一步”按钮时,我想更新进度条,并用新值重新加载表视图。行数必须等于集合数,但每个练习的集合数不同,因此我希望动态更改行数Ios 在获取数据期间,节中的行数索引超出范围,ios,swift,xcode,firebase,Ios,Swift,Xcode,Firebase,当尝试用我的tableview和进度条打开新控制器时,我的“索引超出范围”。 我从Firestore数据库获取数据,其想法是,当我点击“下一步”按钮时,我想更新进度条,并用新值重新加载表视图。行数必须等于集合数,但每个练习的集合数不同,因此我希望动态更改行数 class StartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { var titleValue: String = &q
class StartViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var titleValue: String = ""
var dayOfWorkout: String = ""
var exerciseNumber = 0
var models: [DataCell2] = []
let user = Auth.auth().currentUser
var db = Firestore.firestore()
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var exerciseLabel: UILabel!
@IBOutlet weak var progressView: UIProgressView!
override func viewDidLoad() {
super.viewDidLoad()
progressView.transform = progressView.transform.scaledBy(x: 1, y: 3)
tableView.delegate = self
tableView.dataSource = self
retrieveWorkouts()
}
@IBAction func nextButtonPressed(_ sender: UIButton) {
nextExercise()
Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
tableView.reloadData()
}
@objc func updateUI() {
progressView.progress = getProgress()
}
func getProgress() -> Float {
return Float(exerciseNumber) / Float(models.count)
}
func nextExercise() {
if exerciseNumber + 1 < models.count {
exerciseNumber += 1
} else {
exerciseNumber = 0
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
**//HERE IS ERROR**
return models[exerciseNumber].sets!
}
您是基于行数的
models[exerciseNumber]。集合代码>
您正在设置中的练习编号
func nextExercise() {
if exerciseNumber + 1 < models.count {
exerciseNumber += 1
} else {
exerciseNumber = 0
}
}
有一些更聪明的方法可以做到这一点,但这一点目前仍然有效。您是基于行数计算的
models[exerciseNumber]。集合代码>
您正在设置中的练习编号
func nextExercise() {
if exerciseNumber + 1 < models.count {
exerciseNumber += 1
} else {
exerciseNumber = 0
}
}
有更聪明的方法可以做到这一点,但这一点目前仍然有效。您有一个时间问题。视图将在加载时尝试创建tableView。此时,模型数组将为空,因为异步firebase方法不会运行和更新它。但您将exerciseNumber初始化为0
这意味着numberOfRowsInSection
delegate方法将尝试访问模型[0
],但由于此时数组为空,因此不存在,并导致索引超出范围崩溃
您可以通过一些防御性编程来解决此问题:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard !model.isEmpty else {return 0}
return models[exerciseNumber].sets!
}
您还可以添加第二个保护或先决条件,以确保exerciseNumber您有一个时间问题。视图将在加载时尝试创建tableView。此时,模型数组将为空,因为异步firebase方法不会运行和更新它。但您将exerciseNumber初始化为0
这意味着numberOfRowsInSection
delegate方法将尝试访问模型[0
],但由于此时数组为空,因此不存在,并导致索引超出范围崩溃
您可以通过一些防御性编程来解决此问题:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard !model.isEmpty else {return 0}
return models[exerciseNumber].sets!
}
您还可以添加第二个保护或先决条件,以确保exerciseNumber尝试在retrieveWorkouts
方法内的主线程上调用重新加载数据。您确定nextExercise中的逻辑吗?我认为您在它里面切换了if和else条件。不幸的是,在主线程中重新加载数据不起作用,尽管如此,您还是应该这样做。你确定下一步的方法吗?是的,我确定。唯一不起作用的是在section函数中将集合数检索为行数。这有点离题,但您不会希望在snapshotDocuments中的文档的for循环中反复重新加载tableView。在此之后移动重新加载,以便在填充数据源后只需执行一次。尝试在retrieveWorkouts
方法内的主线程上调用reloadData
。您确定nextExercise中的逻辑吗?我认为您在它里面切换了if和else条件。不幸的是,在主线程中重新加载数据不起作用,尽管如此,您还是应该这样做。你确定下一步的方法吗?是的,我确定。唯一不起作用的是在section函数中将集合数检索为行数。这有点离题,但您不会希望在snapshotDocuments中的文档的for循环中反复重新加载tableView。在此之后移动重新加载,以便在填充数据源后只需执行一次。不幸的是,它仍然无法工作。但是我怀疑我在nextExercise中的逻辑是否错误,因为我从exerciseNumber=0开始,如果exerciseNumber大于models.count我递增,但当exerciseNumber等于models.count时,我的exerciseNumber将再次为0,因此我将从头开始,这里出了什么问题?我道歉-我把它误读为如果练习
。在阅读、剪切和粘贴时,我设法错过了+1
位。我的错!不幸的是,它仍然不起作用。但是我怀疑我在nextExercise中的逻辑是否错误,因为我从exerciseNumber=0开始,如果exerciseNumber大于models.count我递增,但当exerciseNumber等于models.count时,我的exerciseNumber将再次为0,因此我将从头开始,这里出了什么问题?我道歉-我把它误读为如果练习
。在阅读、剪切和粘贴时,我设法错过了+1
位。我的错!谢谢你,伙计,真管用!谢谢你,伙计,真管用!