How to make row selected when moving between multiple views - ios

I am working on xamarin.ios. I have a UITableView control at my view. I select a row in it and then move to next screen. If I come back to UITableView screen again the selected row doesn't highlight. It highlight for a second and then deselect automatically. How it can be managed if I come back to the tableview, the selected row should be highlighted.

Hard to say without seeing any code, but looks like the tableview is being reloaded in viewDidAppear. You may want to store the selected row index in NSUserDefaults or somewhere else to persist the selection between view loads/appearances.
Make sure you are setting it selected after the tableview reloads as well, using an appropriate delegate method. Again, without any code to look at, it's hard to see where - and which order - you're doing this, but an example (Swift):
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == tableView.numberOfRowsInSection(0) - 1 {
cell.selected = true
}
}
Alternatively, you could set the selected property in your datasource directly, and then you could do:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
datasource[indexPath.row].selected == true {
cell.selected = true
}
}
If you do it this way, then the selected row will always be set correctly every time the tableview is loaded.
(Full disclosure, I'm not a Xamarin dev, so I'm not sure how those translate from Swift/Obj-C to Xamarin)

Related

How to determine when the cells in a tableView are returned so as to add a uiview after its finished?

I'm working with some legacy code and it looks like they added a custom sticky header view in the viewDidLoad. The issues is that I need to add the sticky header view AFTER the other cells are returned so that I may send the sticky header view to the back of the other cells so it can be used as a background for the topmost cell.
like so:
homeScreenTableView.sendSubviewToBack(headerView)
or
homeScreenTableView.insertSubview(headerView, at: 0)
The issue is there is no call back after the cells are returned in a tableView. I know this is a bit hacky, but is there a way to do this?
You check if the last indexPath in indexPathsForVisibleRows array has been displayed on screen.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let lastVisibleIndexPath = tableView.indexPathsForVisibleRows?.last {
if indexPath == lastVisibleIndexPath {
// finished loading
}
}
}

UITableViewCell styling resetting when scrolled off and back onto view

I currently have a TableView in my project, which is set up to turn a cell green when it is pressed, and back to clear if it is pressed a second time. However, if I scroll down to the bottom of the table view, and scroll back up, all my cells have been reset to their default clear colour.
I'm not sure how to go about fixing this issue, as anything I can find referring to it is in Objective-C rather than Swift. Any help and advice as to how to go about this would be great, thanks.
Everytime a UITableViewCell goes out of the screen, any function that you've written in the tableViewController/ViewController runs again.
for example in cellForRowAtIndexPath if you have a cell.setUpCell() or something similar, it will rerun and reset your values to the original values.
if you have a
var name = testName in your MainVC
and you update something in your cell, you should change the name in your mainVc too.
Every time you scroll or call tableView.reloadData() UITableView cells will reload. So, every time you select UITableViewCell, add selected index (indexPath.row) to an array(ex: selectedIndexArray) in your didSelectRowAt indexPath: delegate. If the cell you selected is already selected one, then remove the cell from selectedIndexArray.
And in your cellForRowAt indexPath: manage the cells using selectedIndexArray.
var selectedIndexArray:[Int] = [] //to save selected tableViewCells
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let isSelected = false
for each in selectedIndexArray
{
if each == indexPath.row
{
isSelected = true
}
}
if isSelected == true
{
//set selected cell color
}
else
{
//set default cell color
}
}
You need to write the logic of adding and removing cell indexes in your didSelectRowAt indexPath:.

UITableView multi selection and swipe actions

I have a UITableView that has multi selection enabled. I have been using the "selection" to actually change the height of the rows, showing extra detail when "selected". E.g.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return (self.tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false) ? 200 : 92
}
This seems to work pretty well. Until I start doing any swipes actions. When I add some swipe actions, the swipe action seems to clear all of my selections. I actually wanted to deselect the one I was swiping, so it would shrink back down. But the clearing of all my selections doesn't seem to trigger any of the normal delegate callbacks. Even though I have allowsMultipleSelectionDuringEditing set to true.
Is there a way to do this? Should I skip (ab)using the selection state as a way to indicate whether the row is showing details with a different height or not? Or is there a way to use it in conjunction with the behavior of the swipes being done in "edit mode" and clearing all of my selections?
The best way is using NSArray to store indexPath of selected cells, and base on saved indexPath you can check and do anything you want. another bug may happened in your code is: What happened in the case user make scroll on tableview? Does cell will reuse and lose select state? New cell reuse the old cell with 200 height will has wrong height?

How to set the background color of selected row in tableview which is child tableview?

I have a tableview which is inside the a tableview cell.
After click the "JAVA" inside "test1", I click the "About" Row which don't have the tableview inside:
But you can see that, the "About" and "JAVA" have the background colour at the same time. This is the automatic feature of tableview in iOS, I don't know how to code to prevent this happen. What I want is that when I click the "Java" inside "test1", the background color of "About" would disappear.
You are going to need to keep track of which cell was selected if you only want one cell selected at a time from both table views.
The best way to do that is to create a delegate for the nested tableview. So when that cell is selected it can call back to the parent tableview and let it know to unselect anything that was selected. The main class will need to keep track of the index that was selected as if another one is chosen then it can reach into the cell with selected cell and deselect that.
A little tricky, are you sure you can't get the same results from just using one tableview and multiple sections?
Use this code it helps you
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
selectedCell.contentView.backgroundColor = UIColor.greyColor()
}
To deselect the selected row use this code
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
var cellToDeSelect:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
cellToDeSelect.contentView.backgroundColor = colorForCellUnselected
}

Expand UITableViewCell with multiple sections

I want to expand my UITableViewCells with a UITableView that has multiple sections. The way I'm doing it is as follows:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRowIndex = indexPath
habitTableView.beginUpdates()
habitTableView.endUpdates()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (selectedRowIndex != nil && indexPath == selectedRowIndex!){
return 147
}
return 90
}
However there are some strange behaviors, for example, if one cell expands it sort of "eats up" the next section header underneath it so the section header disappears. I am just wondering - is there any nuances with a UITableView that has multiple sections?
So, you can do one thing is to have two protocol type of UITableViewCell. One is for normal and another one is for expanded. Once you type on a cell, you just need to update the delegate to use expanded one instead normal one. When updating, you only need to call reloadRowsAtIndexPaths to prevent reload everything.
You only need to create one more cell prototype and have a boolean value for indicating the state. Then, add your logic to cellForRowAtIndexPath.

Resources