Reputation: 165
I am trying to find a way that allows me to insert a new cell under a specific section on my tableview. There is a button that is pressed called "add song" and once a user presses on that it should insert a new cell that is built by with a prototype cell. That prototype cell will allow a user to click on it and edit certain information on that cell. I have been trying to code a way to insert the cell below the cell that is currently in that section which is section "3". I'm sure it is something simple that I am messing up since I'm not very use to doing tableviews. Here is my code:
import UIKit
class MultipleSongsTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addSong(_ sender: Any) {
insertNewSongCell()
}
func insertNewSongCell() {
let indexPath = IndexPath(row: -1, section: 3)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}
}
extension MultipleSongsTableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else if section == 1 {
return 1
} else if section == 2 {
return 1
} else if section == 3 {
return 1
} else {
return 1
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "trackTitleCell", for: indexPath) as! ReleaseTitleTableViewCell
return cell
} else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "genreCell", for: indexPath) as! Genre2TableViewCell
return cell
} else if indexPath.section == 2 {
let cell = tableView.dequeueReusableCell(withIdentifier: "TrackListCell", for: indexPath) as! TrackListTableViewCell
return cell
} else if indexPath.section == 3 {
let cell = tableView.dequeueReusableCell(withIdentifier: "TrackListSongCells", for: indexPath) as! TrackListSongsTableViewCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "AddSongButtonCell", for: indexPath) as! AddSongTableViewCell
return cell
}
}
}
Also here is a screenshot of how my viewcontroller looks and where I expect the new cell to populate.
I would like the new cell to be inserted after the cell that says "Song Name", I would like the inserted cell to be the same prototype cell that is currently there because the user can click on that cell and fill out information and change the current "Song Name" label to what ever they want.
Upvotes: 0
Views: 897
Reputation: 285072
First of all you need a data source array for the section for example
var songs = [String]()
Then you have to modify numberOfRowsInSection
to return the number of songs for section 3. This method can be simplified anyway
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 3: return songs.count
default: return 1
}
}
Now you can add a new song to the array and insert the row
func insertNewSongCell() {
let insertionIndex = songs.count
songs.append("New Song")
let indexPath = IndexPath(row: insertionIndex, section: 3)
tableView.insertRows(at: [indexPath], with: .automatic)
}
beginUpdates
and endUpdates
have no effect in this case, you can omit the lines.
Upvotes: 2
Reputation: 181
Calling UITableView.insertRows(at:with:) will insert cells into your UITableView
. You can insert exactly 1 cell by passing an indexPaths
argument containing 1 IndexPath
:
self.tableView.insertRows(at: [IndexPath(row: 1, section: 3)], with: .automatic)
You may need to also update your UITableViewDataSource
to return expected values, e.g. from its tableView(_:numberOfRowsInSection:), to account for the additional row(s). Otherwise, your app will throw an unhandled exception and crash.
Upvotes: 1