0

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

10
  • swap should work technically, what did u mean by it did not work? Commented May 14, 2020 at 8:03
  • Using commands[stack]!.swap(oldIndex, suggstedIndex) made out of range exception. Commented May 14, 2020 at 8:06
  • that means getCommandStackIndex is returning wrong value, can u please show implementation of it Commented May 14, 2020 at 8:09
  • @SandeepBhandari I edited my text, note I tried to use object instead of integer due to 0 returned if key doesn't exists and 0 may be a row in my Table :) Commented May 14, 2020 at 8:14
  • so I assume you save index as the value in user default against command_commondID_index correct? How do u save it? show that code may be while saving index you might be incrementing the value, so instead of saving index 0 for first cell you might be saving 1. common mistake of not realising Array indexing starts at 0 not 1 Commented May 14, 2020 at 8:25

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, you're right. I have to check if indexes are existent before

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.