TableView section header moves when a row is edited - ios

I'm building an iOS app with a tableView, it's using a Realm database for the datamodel. When I try to delete a row by dragging the cell towards left, the section header follows the dragging movement to the left. When delete is pressed, the cell is deleted and the section header moves back into the right place.
Any clues to why the section header is moving with the cell?
The header cell is defined in the storyboard as a dynamic prototype cell, and the row cells are defined in a seperate xib and registered in the tableview. The section cell has the "Indent While Editing"-option unchecked in the storyboard.
The "Weekly report" is in the section header.
Here is the code I've implemented to enable editing:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
try! realm.write {
let reportToDelete = reportList[indexPath.row]
realm.delete(reportToDelete)
tableView.deleteRows(at: [indexPath], with: .fade)
}
}
}
I've tried both on the device and two different simulators, and with cleanin the build folder.
EDIT
The header is loaded from the storyboard, where it has a reuseable identifier: "WeeklyReportHeader", and the UIView in return by the tableView's delegate.
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return tableView.dequeueReusableCell(withIdentifier: "WeeklyReportHeader")! as UIView
}

I think this has something to do with using a cell as the header, probably some issue to do with cell reuse.
To fix this, rather than using the cell itself (and casting it as a UIView for the header), use it's contentView property, which is a UIView anyways.
Eg
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return tableView.dequeueReusableCell(withIdentifier: "WeeklyReportHeader")!.contentView
}

Related

UITableView embeded in NavigationController and UITabBar won't Scroll

I am currently learning IOS. I have UITableView embedded in NavigationController and UITabBar. I have populated the TableView with data and its showing in the table when I run the app. The TableView is not scrolling and for the life of me I can't figure out why.
Here is the table view code
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return petitions.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
// code to initialize the cell here
return cell
}
Any suggestions as to what am missing, or how to make it work is welcomed
Maybe if you changed your table view scroll options. So table view is a scroll view. Options must be like below:

When deleting row using trailingSwipeActionsConfigurationForRowAt strange missing other rows issue

I am trying to delete row from UITableView by using trailingSwipeActionsConfigurationForRowAt function.
The row gets deleted and disappears. This part is ok.
But next rows that are coming to the screen or when I swipe down the same amount as the rows been deleted are not even loaded on the tableView.
![img1]https://poirot.deus4.com/photo_2019-06-12_16-44-01.jpg
![img2]https://poirot.deus4.com/photo_2019-06-12_16-43-56.jpg
![img3]https://poirot.deus4.com/photo_2019-06-12_16-43-49.jpg
![img4]https://poirot.deus4.com/photo_2019-06-12_16-43-38.jpg
[video]https://poirot.deus4.com/RPReplay_Final1560345600.mp4
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredProducts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: .cellID, for: indexPath) as! ProductTableCell
cell.backgroundColor = .red
return cell
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let hide = UIContextualAction(style: .destructive, title: "Hide") { action, view, completion in
self.filteredProducts.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
completion(true)
}
hide.image = #imageLiteral(resourceName: "hdie_product")
hide.backgroundColor = .midGrey
let conf = UISwipeActionsConfiguration(actions: [hide])
return conf
}
The code you showed obviously works, thus the problem is elsewhere.
Without other code I suspect that the problem is because table view cells are re-used: When you scroll your table view, some cells are scrolled out of view and can be reused. Cells that are scrolled in are either re-used cells or new cells.
In any case, the table view datasource function tableView(_:cellForRowAt:) must be used to configure the displayed cells.
It seems too me that you do not configure the cells in tableView(_:cellForRowAt:).
If so, re-used cells look as the were when they have been scrolled out, but new cells are simply blank.
So I suggest to check if you really configure all the cells in tableView(_:cellForRowAt:) correctly.
The issue was that I did not call super.prepareForReuse() inside TablewViewCell
override func prepareForReuse() {
super.prepareForReuse() // this was missing
}

swift: Table View Deletes wrong file

I want to delete an item from a table view.
First I added a filePath property on my class (that was missing)
Then I corrected the line of code to find the right filePath
the problem is solved but still I have the wrong file deleted so I check the sync of the arrays.
First, I make sure the table view knows what it shows and it appears the arrays are synced. I debug the code and I find that when I swipe to delete an item the code still deletes another file.
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableOfExpences.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellOfExpencesTableViewCell
let myOneExpense = self.tableOfExpences[indexPath.row]
if myOneExpense.size != nil {
//Arrangement Of the cell
//allocate the right image for each segment
} else {
cell.nameCellLabel?.text = "No Cost"
}
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
self.tableOfExpences.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
print("the removed from the table expence is the \(String(describing: tableOfExpences[indexPath.row].expenseID))")
print("We had bought a \(String(describing: tableOfExpences[indexPath.row].note))")
In my case there was a numerous things why the wrong file was deleted but the most tricky(when all the code seemed to be correct) was that first the file must be removed from the directory and then the cell from the table.
So just reversing the order of lines so that first to delete data from the file
try FileManager.default.removeItem(atPath: paths[indexPath.row])
and then to implement the
self.tableOfExpences.remove(at: indexPath.row)
solved the last great problem.

Remove Table View Cell from Table View with if statement

How do I remove a static table view cell by doing a if statement like this:
if ____ {
remove static cell
} else {
keep cell in tableview
}
The bolded part is what I need the code for. I searched the internet for an answer, but I could not find one. Thanks for the help! I'm using Swift 3
First, make sure to change cells to have Dynamic Properties, because static cells are hard-coded.
Second, you don't need an else statement. If the condition is true, delete the cell, otherwise do nothing. To delete a cell, use a function:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("Cell deleted")
// delete any additional data from containers like arrays or dictionaries if needed
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
If this is a static tableview you can't remove a cell. If you attempt to you'll probably fall into all sorts of issues. Your best solution is to set the cell's height to zero and hide it.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAt:indexPath)
if indexPath == cellToHide {
cell.isHidden = true
}
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath == cellToHide {
return 0
}
return super.tableView(tableView, heightForRowAt: indexPath)
}

remove the delete button ⛔️ on table rows in edit mode

I am trying to learn Swift, but there is a problem in my project that drives me nuts.
I have a working list of data in a ViewController fed by parse.com. I managed to implement a swipe-feature that reveals buttons for both deleting and editing. That is working fine. Now I want the user to be able to reorder the cells. So I successfully implemented a button to put the table into editing-mode. My 2 problems with that are:
When I enter edit-mode I just want to be able to reorder the cells since editing and deleting is done via swipe (via "tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath)". How can I achive that the user doesn't see the 2 buttons for deleting and editing when in editing-mode and touching the delete-circle that is provided automatically?
Is it possible to remove the delete-circle altogether? Using "UITableViewCellEditingStyle.None" also disables the swipe-functionality.
Thanks in advance!
To avoid the round red delete button that appears when you put set UITableView isEditing to true at the left and does nothing when you click it, the minimum that worked for me was this (Swift 4, iOS 11)
// Avoid the round red delete button on the left of the cell:
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
I also have these functions, which probably interact:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return savedTempTable.isEditing
}
// Including this function in the delegate enable left-swipe deleting
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == .delete {
savedConversions.remove(at: indexPath.row)
}
}
// Including this function enables reordering
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath,to destinationIndexPath: IndexPath)
{
let elem = savedConversions.remove(at: sourceIndexPath.row)
savedConversions.insert(elem, at: destinationIndexPath.row)
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
Although people can delete a row through swipe the delete-button in editing mode should not be removed. People may not know about the swipe gesture and by removing the delete button (which they already expect in editing mode) the app becomes more difficult to use.
If you really want to remove the delete button then you have to implement the delegate method tableView(_:editingStyleForRowAtIndexPath:). There you can return .None while the screen is in editing mode and .Delete while the screen is not.
To enable reordering you have to implement the data source methods tableView(_:canMoveRowAtIndexPath:) and tableView(_:moveRowAtIndexPath:toIndexPath:).
You follow this way to remove the delete Icon while editing:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellAccessoryNone;
}

Resources