How to Loop Through Uitableview's Cells

iPad: Iterate over every cell in a UITableView?

for (int section = 0; section < [tableView numberOfSections]; section++) {
for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:cellPath];
//do stuff with 'cell'
}
}

How can I loop through UITableView's cells?

If you only want to iterate through the visible cells, then use

NSArray *cells = [tableView visibleCells];

If you want all cells of the table view, then use this:

NSMutableArray *cells = [[NSMutableArray alloc] init];
for (NSInteger j = 0; j < [tableView numberOfSections]; ++j)
{
for (NSInteger i = 0; i < [tableView numberOfRowsInSection:j]; ++i)
{
[cells addObject:[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]]];
}
}

Now you can iterate through all cells:

(CustomTableViewCell is a class, which contains the property textField of the type UITextField)

for (CustomTableViewCell *cell in cells)
{
UITextField *textField = [cell textField];
NSLog(@"%@"; [textField text]);
}

Loop through a uitableviewcell on submit in swift 4

You seem to acknowledge that updating the model directly probably makes sense. So why not do that? Just:

  1. Have model collection for the responses;
  2. Set up delegate for the text field in the cell;
  3. Have cellForRowAt set that delegate; and
  4. Make the table view controller conform to that class.

So, something quick and dirty, set up the cell to hook up editChanged event from the text field and set up protocol to inform the view controller:

protocol FormTableViewCellDelegate: class {
func fieldValueChanged(cell: UITableViewCell, textField: UITextField)
}

class FormTableViewCell: UITableViewCell {

weak var delegate: FormTableViewCellDelegate?

@IBOutlet weak var formLabel: UILabel!
@IBOutlet weak var formTextField: UITextField!

@IBAction func editingChanged(_ sender: UITextField) {
delegate?.fieldValueChanged(cell: self, textField: sender)
}

}

And then have the view controller set up model object and conform to your new protocol:

class FormTableViewController: UITableViewController {

var formLabels = [String]()
var formPlaceholders = [String]()
var values = [String?]()

override func viewDidLoad() {
super.viewDidLoad()

...

formLabels = ["Name","Email","Password", "Phone"]
formPlaceholders = ["John Smith","example@email.com","Enter Password", "8585551234"]
values = [nil, nil, nil, nil]
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FormTableCell", for: indexPath) as! FormTableViewCell

let row = indexPath.row
cell.formLabel.font = .preferredFont(forTextStyle: .headline)
cell.formLabel.text = formLabels[row]
cell.formTextField.placeholder = formPlaceholders[row]
cell.formTextField.text = values[row]
cell.delegate = self // set the delegate, too
return cell
}

@IBAction func submitButtonPressed(_ sender: Any) {
print(#function, values)
}

}

// delegate protocol to update model as text fields change

extension FormTableViewController: FormTableViewCellDelegate {
func fieldValueChanged(cell: UITableViewCell, textField: UITextField) {
guard let indexPath = tableView.indexPath(for: cell) else { return }

values[indexPath.row] = textField.text
}
}

Then that's it, your model is updated as the text fields are updated. Plus this has the advantage that it now supports cell reuse, conforms to MVC patterns, etc.

How to Iterate through all UITableView sections?

I was able to iterate through all UITableView sections and row through code below:

The logic here is that to be able to get the right subview that I've appended to the cell.contentView, I've set them with a tag before adding them as Subview, so that I would be able to get the exact view that I've added instead of the wrapping contentView.

var subviews = [UIView]()
let sectionCount = tableView.numberOfSections

/// loop through available sections
for section in 0..<sectionCount {

/// get each section headers
if let sectionHeader = self.tableView(tableView, viewForHeaderInSection: section) {
subviews.append(sectionHeader)
}

if tableView.numberOfRows(inSection: section) > 0 {
/// loop through rows within section
for row in 0..<tableView.numberOfRows(inSection: section) {
let indexPath = IndexPath(row: row, section: section)
tableView.scrollToRow(at: indexPath, at: .top, animated: false)
if let currentCell = tableView.cellForRow(at: indexPath), let view = currentCell.contentView.viewWithTag(999) {
subviews.append(view)
}
}
}
}

Loop through individual UITableViewCells in UITableView in order to edit text in cells

You should first understand what are you doing and what you want to do. Get good understanding of UITableView

You do not need the while loop and also cellForRowAtIndexPath calls for each visible cells(These cells reused for other index paths).

//Remove while loop and var i = 0

//This will call for each visible cell so replace `i` with indexPath.row
if globalVariable.specialBool[indexPath.row] == true {
// do your work here
}

UITableView is Looping Through Cells (That I Don't Want it to)

I think you need to implement in you custom cell:

func prepareForReuse() {
super.prepareForReuse()
itemTitle.text = ""
//... and so on
}

Just clean up the field of your cell inside this method.

How to iterate a for loop in table view cell swift

The basics of what you are trying to do are to get a value from the data source, convert it to a number if needed and then total them up.

For your example above, this would do the trick:

let news = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

let total = news.map({ Int($0)! }).reduce(0) { x, y in
return x + y
}

print(total) // 55

To do this for a shopping cart, your data source will likely be a list of products instead, maybe something like:

struct Product
{
var name: String
var price: Int
var quantity: Int
}

let prod1 = Product(name: "Coka Cola", price: 2, quantity: 2)
let prod2 = Product(name: "Bread", price: 1, quantity: 1)
let prod3 = Product(name: "Sweets", price: 2, quantity: 4)

let shoppingCart = [prod1, prod2, prod3]

let total = shoppingCart.reduce(0) { x, y in
return x + (y.price * y.quantity)
}

print(total) // 13

Its the same principal, just a little more complicated. As long as your data structure is right it should be straight forward



Related Topics



Leave a reply



Submit