Reputation: 140
I'm blocked on an issue. It began with TableView moving row logic so I have to reflect it into my model and then save the row in UserDefaults
.
Later, I'm reusing the index saved into UserDefaults
and I want to reorder my array with this index.
Basically I tried this:
// in a commands.keys loop -> stack
// in a commands[stack]! loop -> command
guard let suggestedIndex = AllCommands.getCommandStackIndex(commandId: command.id) else { continue }
guard let oldIndex = commands[stack]!.firstIndex(where: { $0.id == command.id }) else {
fatalError()
}
commands[stack]!.insert(commands[stack]!.remove(at: oldIndex), at: suggestedIndex)
And I also tried arr.swap(Int, Int)
but it was unsuccessful.
I'm facing Array index out of range and I would like to know if there is a better option to achieve this or fix this issue.
static func getCommandStackIndex(commandId: Int) -> Int? {
UserDefaults.standard.object(forKey: "command_\(commandId)_index") as? Int
}
static func setCommandPosition(commandId: Int, stack: ActionViewStackPosition, stackIndex: Int) {
UserDefaults.standard.removeObject(forKey: "command_\(commandId)_index")
UserDefaults.standard.removeObject(forKey: "command_\(commandId)_stack")
UserDefaults.standard.set(stackIndex, forKey: "command_\(commandId)_index")
UserDefaults.standard.set(stack.rawValue, forKey: "command_\(commandId)_stack")
print("--- Saved occurrence for id: [\(commandId)] in index: [\(stackIndex)] & stack: [\(stack)] ---", #function)
}
// SettingsTableViewController
private func saveNewPositions(before: IndexPath, new: IndexPath) {
guard let command = commands[before.section]?[before.row] else {
print("Missed align between [\(before.section)][\(before.row)]")
return
}
var section: ActionViewStackPosition
switch new.section {
case 0:
section = .top
case 1:
section = .bottom
case 2:
section = .inactive
default:
fatalError("Hun?")
}
AllCommands.setCommandPosition(commandId: command.id, stack: section, stackIndex: new.row)
}
// Called by
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
saveNewPositions(before: sourceIndexPath, new: destinationIndexPath)
}
Regards
Upvotes: 0
Views: 77
Reputation: 151
If you need to have two items in an array change places, the swapAt() method is exactly what you want: provide it two indexes inside your array, and the items at those positions will be swapped.
For example, consider this array:
var names = ["Paul", "John", "George", "Ringo"]
If I wanted John and Paul to swap places, I’d swap positions 0 and 1, like this:
names.swapAt(0, 1)
Note: swapAt() will trigger a fatal error if you try to swap beyond the length of the array. What was your suggestedIndex? Perhaps it was outside the bounds of your array? Try adding a check to make sure the two indexes you’re trying to swap are actually within the bounds of the array.
https://developer.apple.com/documentation/swift/array/2893281-swapat
Upvotes: 2