How do i disable unused rows of UITableView (Swift)? - swift

When it comes to creating a dynamic type table view in a storyboard, it automatically fills up the table with rows.
How would i disable the red lined section (unused rows yet) of the image?

Use tableView(_:cellForRowAt:) method from UITableViewDataSource, like so
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellId", for: indexPath)
if indexPath.section == DISABLED_SECTION_INDEX {
cell.isUserInteractionEnabled = false
} else {
cell.isUserInteractionEnabled = true
}
}
Or without if statement
cell.isUserInteractionEnabled = indexPath.section != DISABLED_SECTION_INDEX

Related

Crash: Attempted to dequeue multiple cells for the same index path, which is not allowed

I have tableview datasource func to build a cell from a factory method function.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return OWTableViewOrganizer.instance.configureCell(at: indexPath)!
}
The factory method is here:
func configureCell(at indexPath: IndexPath) -> UITableViewCell? {
var cell = UITableViewCell()
switch indexPath.section {
case thisWorkoutSections.barbel.sectionNumber():
cell = barebellCell(indexPath: indexPath)
break
case thisWorkoutSections.lastWorkout.sectionNumber():
cell = lastWorkoutCell(indexPath: indexPath)
break
case thisWorkoutSections.personalRecord.sectionNumber():
cell = personalRecordCell(indexPath: indexPath)
break
case thisWorkoutSections.notes.sectionNumber():
break
default:
break
}
return cell
}
I have this code to build the cell:
func lastWorkoutCell(indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: WorkoutSetTableViewCell.cellIdentifier(), for: indexPath) as! WorkoutSetTableViewCell
if OWTableViewOrganizer.instance.lastWorkoutExerciseSets.count > 0 {
if indexPath.row < OWTableViewOrganizer.instance.lastWorkoutExerciseSets.count {
let logExerciseSet = OWTableViewOrganizer.instance.lastWorkoutExerciseSets[indexPath.row]
let setNumber = indexPath.row + 1
if let weight = logExerciseSet.weight?.doubleValue, let reps = logExerciseSet.reps?.intValue {
cell.setupCellWithData(setNumber: setNumber, weight: weight, reps: reps)
}
} else {
cell.setupCellWithData(setNumber: -1, weight: 0, reps: 0)
}
} else {
cell.setupCellWithData(setNumber: -1, weight: 0, reps: 0)
}
return cell
}
But time to time this line crashes for me:
let cell = tableView.dequeueReusableCell(withIdentifier: WorkoutSetTableViewCell.cellIdentifier(), for: indexPath) as! WorkoutSetTableViewCell
With error:
Attempted to dequeue multiple cells for the same index path, which is not allowed. If you really need to dequeue more cells than the table view is requesting, use the -dequeueReusableCellWithIdentifier: method (without an index path)
I know code style and design is not ideal here, please skip this if you have comments.
I don't know where to look, I tried simply remove indexPath, but it looks does not help or bring even more issues:
let cell = tableView.dequeueReusableCell(withIdentifier: WorkoutSetTableViewCell.cellIdentifier()) as! WorkoutSetTableViewCell
I have one controller which presents another one at the top of it (like in Apple music) and I can swipe down to show bottom controller and swipe up to bring back top controller. I noticed in log that I have some presentation alert, not sure if this something I need to deal with to resolve the issue above but JFY info.
It seems like there are two table view trigger
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
and you only dequeue cell from 1 table view at
let cell = tableView.dequeueReusableCell(withIdentifier: WorkoutSetTableViewCell.cellIdentifier(), for: indexPath) as! WorkoutSetTableViewCell
You should try to pass tableView from
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
to
lastWorkoutCell(indexPath: IndexPath)
(which will become lastWorkoutCell(indexPath: IndexPath, tableView: UITableView)) and dequeue cell from tableView

Set the colour of all the labels in tableview

How would I set the colour of each label in table view section using swift?
I have done this but it does not work.
Thanks
for section in 0..<tableView.numberOfSections {
for row in 0..<tableView.numberOfRows(inSection: section) {
let indexPath = NSIndexPath(row: row, section: section)
var cell = tableView.cellForRow(at: indexPath as IndexPath)
if (cell as? UILabel) != nil {
cell?.textLabel?.textColor = .red
}
}
}
You should be set the cell's properties inside the cellForRowAt method, like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: <#T##String#>, for: indexPath)
cell.textLabel?.backgroundColor = .red
return cell
}
You are making a conflict with type.
In this line you are assigning the cell type to variable cell
var cell = tableView.cellForRow(at: indexPath as IndexPath)
And In this line of code you are asking if cell is a UILabel then make it text label colour to red.
This will always return false and code inside if will never execute.
if (cell as? UILabel) != nil {
cell?.textLabel?.textColor = .red
}
Remove the if statement and then execute the code.

Two Table Views in One VC

I want to display two (or more) table views from a single view controller. I mean display simultaneously, e.g., beside each other or one above the other. The only way I can think of doing it is with child view controllers. Is there a better or easier way?
Thanks for your comments.
Yes of course you can use like this:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if tableView == firstTableView
{
let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell1", for: indexPath)
cell.textLabel?.text = "Section \(indexPath.section) Row \(indexPath.row)"
return cell
}
else if (tableView == secondTableView)
{
let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell2", for: indexPath)
cell.textLabel?.text = "Section \(indexPath.section) Row \(indexPath.row)"
return cell
}
else
{
return UITableViewCell()
}
}
Similar to other tableview delegate methods, you should add a condition for each table
If your use case is to have two individually scrolling table views then you can simply add two table views in the xib, assign datasource and delegates and call it a day.
If your use case is to display two types of information on a page I'd recommend using just one table view and handling what to display manually.
Let me know if you need any more help.
Use Switch Condition
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
switch tableView {
case firsttableView:
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.label1.text = "Zaid"
cell.label2.text = "Ahamd"
return cell
case secondTableView:
let cell = tableView.dequeueReusableCell(withIdentifier: "SecondTableViewCell", for: indexPath) as! SecondTableViewCell
cell.labelText.text = "ZaidAfzalMughal"
return cell
default:
print("Something wrong")
}
return cell
}

Tableview cells lines disappear

Does anyone have an official answer as to why some tableview cell lines disappear on scroll? Is this a glitch? I've seen some answers on how to remove them but what is causing this problem to begin with?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "DisplayHeader") as! DisplayTVC
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "PictureDisplay") as! PictureTVC
cell.collectionView.reloadData()
return cell
}
}

how to add checkmark in tableview swift

I'm trying to show checkmark on tableview cell, but the checkmark appears only sometimes and it disappears when I scroll.
Below the code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("vvxxx12", forIndexPath: indexPath)
// Configure the cell...
cell.textLabel?.text = self.dataArray[indexPath.row] as? String //in dataArray values are stored
if dataArray.containsObject(indexPath)
{
cell.accessoryType = .Checkmark
}
else {
cell.accessoryType = .None
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
if cell.accessoryType == .Checkmark {
cell.accessoryType = .None
} else {
cell.accessoryType = .Checkmark
}
}
}
Just do following changes in your code to maintain checkmark into tableview while you are scrolling tableview
Result :
Its work fine now, Any problem let me know i will definitely help you to out.Enjoy..
For Swift 3 following worked for me to
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
yourtableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
yourtableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
}
cell.textLabel?.text = self.dataArray[indexPath.row] as? String
This suggests that dataArray contains strings.
if dataArray.containsObject(indexPath)
This suggests that dataArray contains index paths. Both of these should not be true. One array for data makes sense, and another one for selected rows or rows to be checked also makes sense, but not the same array for both.
What's probably happening is:
Row selected - cell is then updated to have the checkmark accessory
Table scrolled and cellForRowAtIndexPath is called - at no point will dataArray contain an index path, so the accessory is always cleared.
You need to be updating your model when a row is selected, to store the index path of the selected row, or update a selected flag on your model objects.