Disabling all UITableView cells except the last one - Swift - ios

Currently working with UITableView in swift.
Since my table cell values are appending by clicking the button i want to figure out a way to disable interaction for all the previous cells, except the last one.
I've played with array-based approach a little, but it didn't work out the way i wanted.
var disabledRows = [0,1,2]
else
{
cell.backgroundColor = UIColor.orangeColor()
}
if (contains(disabledRows, indexPath.row)) {
cell.userInteractionEnabled = false
}
else {
cell.userInteractionEnabled = true
}
The issue with this approach is that i have to count all cells and then block the last one.
Maybe there are some easier approaches?
Any help much appreciated.
Update - here is my complete "cellForRowAtIndexPath" function
func tableView(tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell
{
let cell: CustomCellForTableViewTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell") as! CustomCellForTableViewTableViewCell
if indexPath.row % 2 == 0
{
cell.backgroundColor = UIColor.purpleColor()
}
else
{
cell.backgroundColor = UIColor.orangeColor()
}
if (contains(disabledRows, indexPath.row)) {
cell.userInteractionEnabled = false
}
else {
cell.userInteractionEnabled = true
}
let quest = arrayOfQuestions[indexPath.row]
cell.setCell(type.Grocery, optionno1:type.option1, optionno2:type.option2)
cell.mainText.text = type.Grocery
cell.optionOne.backgroundColor = UIColor.redColor()
return cell
}

In cellForRowAtIndexPath: method.
if (indexPath.row == yourDataSourceArray.count - 1) {
// enable cell
} else {
// disable cell
}

Related

Multiple selection UITableView without dequeueReusableCellWithIdentifier

When selecting multiple cells in my tabeview the cells out of view are being selected too. I understand that this is because i am reusing the cell and its maintaining its selection as i scroll down. I have found a few people with similar issues but cant translate their solutions across to resolve my issue. I have tried not dequeing a cell and just use:
let cell = NewBillSplitterItemCell()
but get:
unexpectedly found nil while unwrapping an Optional value
on the line:
cell.currentSplitters.text = splitterList
in the following code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
fetchBillItems()
let cell: NewBillSplitterItemCell = tableView.dequeueReusableCellWithIdentifier("NewBillSplitterItemCell") as! NewBillSplitterItemCell
let item = allItems[indexPath.row]
let numberOfSplitters = item.billSplitters?.count
if numberOfSplitters == 0 {
cell.currentSplitters.text = "No one is paying for this item yet."
} else {
var splitterList = "Split this item with "
let itemSplitters = item.billSplitters?.allObjects as! [BillSplitter]
for i in 0...Int((numberOfSplitters)!-1) {
if numberOfSplitters == 1 {
splitterList += "\(itemSplitters[i].name!)"
} else {
splitterList += ", \(itemSplitters[i].name!)"
}
}
cell.currentSplitters.text = splitterList
}
cell.name.text = item.name
cell.price.text = "£\(item.price!)"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
if cell.accessoryType == .Checkmark
{
cell.accessoryType = .None
selectedItems.removeAtIndex(selectedItems.indexOf(allItems[indexPath.row])!)
} else {
cell.accessoryType = .Checkmark
selectedItems.append(allItems[indexPath.row])
}
}
}
I dont quite understand what to do and any help would be great. Thanks
In addition to what #Mike said, inside of cellForRowAtIndexPath you need an additional check because cells get reused.
Something along the line
let isSelected = selectedItems[indexPath.row].selected
if isSelected{
cell.accessoryType = .Checkmark
} else {
cell.accessoryType = .None
}
Same thing inside of didSelectRowAtIndexPath you should update the data source instead of relying on the UI of your cell for that condition.
Assuming your cell is nil, you should use
let cell = tableView.dequeueReusableCellWithIdentifier("..." forIndexPath:indexPath) as! NewBillSplitterItemCell
instead of
let cell= tableView.dequeueReusableCellWithIdentifier("...") as! NewBillSplitterItemCell
This ensures that cell will never be nil.
Also, I would check if the correct identifier is being used in all of your .xib .storyboard files.

TableView gets inconsistent behaviour when scrolling down/up

I have a ViewController that has a TableView. The tableView cell has a StackView with two images in it and outside it a label.
In the tableView:cellForRowAtIndexPath I get the cell and my data is inside a arrayList. And this is what I do:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "NamesTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NamesTableViewCell
let _name = _Names[indexPath.row]
if indexPath.row % 2 != 0 {
cell.backgroundColor = UIColor(hexString: "ededed")
}
cell.labelName.text = _name.name
if _name.gender! == "M" {
cell.pinkCircleImageView.hidden = true
} else if _name.gender! == "F" {
cell.blueCircleImageView.hidden = true
}
return cell
}
So as you can see I hide the images depending on the gender of the name and also change the background of every other cell.
Now, the behavior I am seeing is:
https://gyazo.com/1b2d39696892b7fb2f15b71696d9a925
The gender is available for every object, I've checked.
What do you guys think? Thanks!
cell.pinkCircleImageView.hidden = false
cell.blueCircleImageView.hidden = false
if _name.gender! == "M" {
cell.pinkCircleImageView.hidden = true
cell.bringSubviewToFront(blueCircleImageView)
} else if _name.gender! == "F" {
cell.blueCircleImageView.hidden = true
cell.bringSubviewToFront(pinkCircleImageView)
}
if indexPath.row % 2 == 0
{
cell.backgroundColor=UIColor.whiteColor()
}
else
{
cell.backgroundColor=UIColor(red: 248/255, green: 248/255, blue: 248/255, alpha: 1.0)
}

Why is the second return statement being called and why am I getting the return error?

I have two uitableviews not related to each other at all, but they are on the same view. The animal tableview is showing the information, but animallocation is not displaying anything. I put a breakpoint on the second return statement in the second if statement, but the program does not stop. I am also getting an error (Look below). How do I fix this? the first if statement works. animallocationarray is populated it prints ("Africa", "India", "South America"). I get an error http://puu.sh/mNK2J/549dde1225.png
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(tableView == animal){
var cell: animalCell = self.reviews.dequeueReusableCellWithIdentifier("Cell") as! animalCell
cell.box.text = animalarray[indexPath.row]
if(indexPath.row % 2 == 0){
cell.backgroundColor = RGB("ffffff")
}else{
cell.backgroundColor = RGB("F98233")
}
return cell
}
if(tableView == animallocation){
var cell: location = self.reviews.dequeueReusableCellWithIdentifier("location") as! location
cell.label.text = animallocatioarray[indexPath.row]
if(indexPath.row == 0){
cell.label.textColor = RGB("fffff")
}
if(indexPath.row != 0){
cellvs.vslabel.textColor = RGB("f52654")
}
return cell //placed a breakpoint here but nothing happens
}
}
You miss case Default. You can edit
if(tableView == animal){
var cell: animalCell = self.reviews.dequeueReusableCellWithIdentifier("Cell") as! animalCell
cell.box.text = animalarray[indexPath.row]
if(indexPath.row % 2 == 0){
cell.backgroundColor = RGB("ffffff")
}else{
cell.backgroundColor = RGB("F98233")
}
return cell
}
if(tableView == animallocation){
var cell: location = self.reviews.dequeueReusableCellWithIdentifier("location") as! location
cell.label.text = animallocatioarray[indexPath.row]
if(indexPath.row == 0){
cell.label.textColor = RGB("fffff")
}
if(indexPath.row != 0){
cellvs.vslabel.textColor = RGB("f52654")
}
return cell //placed a breakpoint here but nothing happens
}
To:
if(tableView == animal){
var cell: animalCell = self.reviews.dequeueReusableCellWithIdentifier("Cell") as! animalCell
cell.box.text = animalarray[indexPath.row]
if(indexPath.row % 2 == 0){
cell.backgroundColor = RGB("ffffff")
}else{
cell.backgroundColor = RGB("F98233")
}
return cell
}
var cell: location = self.reviews.dequeueReusableCellWithIdentifier("location") as! location
cell.label.text = animallocatioarray[indexPath.row]
if(indexPath.row == 0){
cell.label.textColor = RGB("fffff")
}
if(indexPath.row != 0){
cellvs.vslabel.textColor = RGB("f52654")
}
return cell //placed a breakpoint here but nothing happens
The function must return a UITableViewCell. Within your code you have two if statements. In the event that both of them fail, no return statement would be executed. That's why your seeing the error - it is a compilation error if there are code paths that do not return the required type.
In your case, one of the two if statements will always be true, but the compiler can't know that. If you recode the second to be an else, instead of another if, there will be no code paths that don't return a value. i.e.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (tableView == animal) {
// animal code
return cell
} else { // i.e. if (tableview == animallocation)
// animallocation code
return cell
}
}
Replace your tableview:cellForRowAtIndexPath: with below code.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(tableView == animal){
var cell: animalCell = self.reviews.dequeueReusableCellWithIdentifier("Cell") as! animalCell
cell.box.text = animalarray[indexPath.row]
if(indexPath.row % 2 == 0){
cell.backgroundColor = RGB("ffffff")
}else{
cell.backgroundColor = RGB("F98233")
}
return cell
}
else{
var cell: location = self.reviews.dequeueReusableCellWithIdentifier("location") as! location
cell.label.text = animallocatioarray[indexPath.row]
if(indexPath.row == 0){
cell.label.textColor = RGB("fffff")
}
else if(indexPath.row != 0){
cellvs.vslabel.textColor = RGB("f52654")
}
return cell //placed a breakpoint here but nothing happens
}
}
In you case, you are returning the cell in if condition,
but also we have to consider the case where if condition will not true,
i.e. else part.

ImageView in UITableViewCell won't display

I've put an ImageView in a UITableViewCell on my Storyboard but at run time it is not showing up on my simulator. How do I solve this?
My storyboard:
The object overview of my storyboard:
The Swift code that fills up the cells:
func tableView(gamesListTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = gamesListTableView.dequeueReusableCellWithIdentifier("Game", forIndexPath: indexPath) as! UITableViewCell
if (indexPath.row < GamesList.count) {
cell.detailTextLabel?.text = GamesList[indexPath.row]["game_guid"].string!;
cell.textLabel?.text = GamesList[indexPath.row]["opponent_name"].string!;
if (GamesList[indexPath.row]["self_turn"] == false) {
cell.textLabel?.textColor = UIColor.greenColor();
} else if (GamesList[indexPath.row]["game_idle_time"] <= 60) {
cell.textLabel?.textColor = UIColor.yellowColor();
} else {
cell.textLabel?.textColor = UIColor.redColor();
}
} else {
cell.detailTextLabel?.text = InvitesList[indexPath.row - GamesList.count]["invite_guid"].string!;
cell.textLabel?.text = InvitesList[indexPath.row - GamesList.count]["invite_text"].string!;
cell.textLabel?.textColor = UIColor.blueColor();
}
return cell
}
What it looks like at runtime:
You should probably pause the execution and view your view hierarchy in Xcode. Check what the frame size it at run time and see if A.) something is overlapping it or B.)If your constraints are wrong.

Multiple cell selection with search

I've created a UITableView which contains a list of teams which all have a accessoryView. This accessoryView indicates whether a cell is selected or not. Each cell is connected with a custom Object in my Team class.
When a cell is selected it then saves the particular team Object in a teamSelected array.
All this works fine. However there seem to be a issue when search and then filter the data and select a cell it seem to add the wrong object and change the accessoryView on a wrong object to?
How come it does to not add the correct object on cell selection when the searchBar is active?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("teamCell", forIndexPath: indexPath) as! TeamCell
if (self.teamSearchController.active) {
cell.textLabel?.text = filteredTableData[indexPath.row].name
} else {
cell.textLabel?.font = UIFont(name: "HelveticaNeue-Light", size: 20)
cell.textLabel?.text = self.teamArray[indexPath.row].name as String
}
let team = self.teamArray[indexPath.row] as Team
var removed = false
for (index, value) in enumerate(self.teamSelected) {
if (value.id == team.id) {
cell.accessoryView = cell.accessoryCheck
removed = true
}
}
if (!removed) {
cell.accessoryView = cell.accessoryUncheck
}
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if (self.teamSearchController.active) {
team = self.filteredTableData[indexPath.row] as! Team
removed = false
} else {
team = self.teamArray[indexPath.row] as Team
removed = false
}
for (index, value) in enumerate(self.teamSelected) {
if (value.id == team.id) {
self.teamSelected.removeAtIndex(index)
removed = true
}
}
if (!removed) {
self.teamSelected.append(team)
}
var userDefaults = NSUserDefaults.standardUserDefaults()
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(self.teamSelected)
userDefaults.setObject(encodedData, forKey: "teams")
userDefaults.synchronize()
tableView.reloadData()
}
I have done this in objective c. I have also used uisearchview Controller. I have use this code. cellSelected is a nsmutable array. Use this code in didSelect method of table View.
if (tableView == self.searchDisplayController.searchResultsTableView)
{
if ([self.cellSelected containsObject:[self.searchArray objectAtIndex:indexPath.row][#"id"]])
{
[self.cellSelected removeObject:[self.searchArray objectAtIndex:indexPath.row][#"id"]];
}
else
{
[self.cellSelected addObject:[self.searchArray objectAtIndex:indexPath.row][#"id"]];
[self.selectedCategoryArray addObject:getSelectedCategory];
}
}
after this use this code in cellforrowatindexpath method
if (tableView == self.searchDisplayController.searchResultsTableView)
{
NSLog(#"self.searchArray..%#",self.searchArray);
titleName.text = [self.searchArray objectAtIndex:indexPath.row][#"name"];
if ([self.cellSelected containsObject:[self.searchArray objectAtIndex:indexPath.row][#"id"]])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
In the above code make else and use your actual array. hope this will help you. Thanks

Resources