How to append a cell to a tableview using iOS 9? - swift

I am using Xcode 7.3 with iOS 9 and Swift. I would like a user to be able to enter an integer into a textfield, tap a button, and then have the integer display in a tableview on the same screen. I would like the user to be able to create a list of integers doing this.
I have my textfield, button, and tableview created. What's the easiest way to code this function?

I am guessing the you know how to use the standard table view, so that I don't have to post irrelevant code?
Try this.....
Use beginUpdates and endUpdates for insert new cell when button clicked..
First of all append data in your tableview array, let's say the array containing the content for your table view is named Yourarray
Yourarray.push(0815) // some integer, which you will grap from the input
Then upate your table and insert new row
// Update Table Data
tblname.beginUpdates()
tblname.insertRowsAtIndexPaths([
NSIndexPath(forRow: Yourarray.count-1, inSection: 0)
], withRowAnimation: .Automatic)
tblname.endUpdates()
You can see the line of code with Yourarray.count-1. There you can write any integer in which line you want to append the new cell.
If you are using a tableview you should be using an array to populate it with the tableview, I hope you are doing that.
Edit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
...
}
firstly you adopt your class from UITableViewDelegate and UITableViewDataSource .
Then you add these functions inside your class:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0 // how many tableview cells you want to display
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell // "cell" is the identifier in this case, change that in your storyboard
cell.textLabel?.text = "Your value for the tableview"
return cell
}
Inside the viewDidLoad you have to add this in order to hook it up:
self.zipTable.delegate = self
self.zipTable.dataSource = self

Related

How to pass all info from multiply table views cells with the info INSERTED to a new view controller?

#objc func addRow(sender: UIButton!) {
print("add")
names.insert("New Name", at: 0)
tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .right)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCell.EditingStyle.delete {
names.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableView.RowAnimation.automatic)
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// if section == 1 {
// return carArray.count
// }
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: bondeCellId, for: indexPath) as! BondCell
//
// if let lbl = cell.contentView.viewWithTag(101) as? UILabel {
// lbl.text = names[indexPath.row]
// }
//
// if let btnDelete = cell.contentView.viewWithTag(102) as? UILabel {
// btnDelete.addTarget(self, action: #selector(deleteRow()), for: .touchUpInside)
// }
return cell
}
enter image description hereI am fairly knew to programing and don’t know a lot.
I have built table view that lets the user add more table cells if they press the add button.
So the user will add more table views on depending if more information is needed.
The problem is to understanding is how to pass all info from multiply table views cells with the info to a new view controller.
If the User has insert 5 or 10 table cells I want those table cells info to be passed into a one new view controller.
The table view cell contains two text fields and two labels and the text field contains UIpickers and depending what they chose it updates in the labels in cell tables.
But I also want sum of all the table views chosen by the user to be added to a chart that I am making to a new view controller.
Would the labels and the text fields need to get new names each time a new table cell is made?
I am stock with ideas
If the User has insert 5 or 10 table cells I want those table cells info to be passed into a one new view controller.
The code you posted is a mess, and not very helpful with your question. It's mostly boilerplate.
You are thinking about this wrong. Cells don't store data. More generally, view objects don't store data. They display data.
You need a model object that stores the data for your table view. It looks like your table view only has one section, so a simple array would work just fine. Create a struct to hold the info you collect from the user. Let's call that struct CellData. Your model would be an array of CellData structs.
As the user creates new cells, you'd collect the new info and add it to your array.
Then when the user selects cells, and invokes the new view controller, you'd pass the whole array, along with the indexes of the selected cells, to the other view controller. (or perhaps just the structs for each selected item.)

How to get didselectrowat from a custom cell with textboxes?

I have a dynamic tableview with 3(cell1,cell2,cell3) custom cells, which gets reused anywhere from 0 times up to 9 times. (Maximum cells in the tableview will be 27 cells).
Each of those 3 custom cells have 3 text boxes each, and in addition the second cell has 2 buttons to select gender and 3rd custom cell has a drop down menu, which has values of whatever typed in the first textbox of cell1 cells.
Now the issue is that, textbox takes the touch input from user (as it should) and didselectrowat never gets called and therefore i am not getting indexPath.
But i need the indexPath, so that i can insert user details from each of those cells into an array.
(anArray.insert("", at: indexPath)
Since i am not getting indexPath, everything fails. How can i get the indexPath and get the touch on to the textbox?
I am thinking of something like a function that takes the touch ,gets the indexPath and then passes the control to textbox.
Things i have tried.
I disabled the textboxes before user touches the cell (and makes textboxes disabled once user deselects the cell, so cell takes the touch. Once didselectrowat gets called, make the textbox active again and make
textbox.becomeFirstResponder()
But somehow , the textbox never becomes the first responder even though breakpoint shows the control going through it and the textbox becomes active. But no keyboard popsup, if i touch the cell again, same process happens.
What seems to be the issue here? I saw another post on the same topic, i tried it but unfortunately that doesnt work and it was for a static tableview.
Also is there a good way to do this? Other than making the user click on the cell twice / clicking outside the textbox..
You can set your custom cell as delegate for UITextField and use a callback for editing begins/ends as below,
class MyCustomCell: UITableViewCell, UITextFieldDelegate {
public var editCallback: (() -> Void)?
/// Set 'textField.delegate = self' on initialization.
func textFieldDidBeginEditing(_ textField: UITextField) {
self.editCallback?()
}
}
And use the callback in cellForRowAt as,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyCustomCell()
cell.editCallback = { [weak self] in
print(indexPath)
}
return cell
}
you can try this
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
//your code here
}

How to modify a custom cell inside of DidSelectRowAtIndexPath

A custom cell class has the override func layoutSubviews() where the detailTextLabel of each cell is given the title "Jim". Upon clicking on DidSelectRowAtIndexPath, is there a way to change the detail text of the cell permanently(to stop the cell from constantly making the detail Jim), to let's say "Bob"?.
//This function is in the custom cell UserCell
class CustomCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
detailTextLabel?.text = "Jim"
}
///........
}
//In the viewController with the tableView outlet
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
//.....
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellId, forIndexPath: indexPath) as! CustomCell
//......
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
/* Code I need to convert the detailTextLabel.text to equal "Bob" upon clicking on certain cell */
}
The cell itself shouldn't be used to hold state for any data, but only to display it. Create a mutable array property on the controller to hold the underlaying data (strings). Set the new cells' text properties by reading this array, and in tableView:didSelectRowAtIndexPath: change the value in the array at the index for "Bob" to "Jim". Whenever the tableView reloads it will now read the updated value from the dataSource.
In addition to the UITableViewDelegate protocol also study the UITableViewDataSource protocol. By default the UITableViewController class conforms to both of these protocols and is assigned as each on its .tableView property (if you introspect its self.tableView.delegate and self.tableView.datasource values you will receive back the original UITableViewController). If you manually created your own tableview controller class that inherits from UIViewController, then you will need to assign both of these properties on the tableView in order for it to function properly.
Very simple, do it like this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
detailTextLabel?.text = "Bob"
}

How to add a custom cell to a dynamicly generated tableview?

Nearly during a week i'm trying to figure out how i can append a static-/custom tableviewcell to a dynamically generated tableview. I'm populating the cells based on the data i'm getting from the database. Basically what i'm trying to accomplish is like the following picture from the app ClassDojo:
As you may know and see, you can add add as many groups as you want with the ClassDojo app, but the latest cell, in this case Voeg een nieuwe klas toe, will always stay at the bottom of the tableview. That's exactly what i'm trying to do.
What i tried to do till this moment is trying to calculate the latest cell in the tableview and trying to append my custom cell, but unfortunately i couldn't get my head around it.
I would really appreciate if someone can help me out with this.
Thanks in advance.
Please let me know if you guys need any code.
---------EDITED POST---------
I did accomplish to assign my custom cell thanks to #Slayter, but now i'm facing with the problem that my custom cell is immediately overwritten by my dynamically created cells (with Alamofire).
Any help would be appreciated.
ClassDojo iOS Engineer here! More than happy to share how we do this.
Like Slayter mentioned, we do
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count + 1 // Add one for your custom cell
}
But in addition we also do the following:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = nil;
if self.indexIsForCustomCell(indexPath) {
cell = tableView.dequeueReusableCellWithIdentifier(CustomCell.reuseIdentifier)
// Additional configuration
} else {
cell = tableView.dequeueReusableCellWithIdentifier(RegularCell.reuseIdentifier)
// Additional configuration
}
return cell
}
Where CustomCell looks something like this (not exact):
class CustomCell: UITableViewCell {
static let reuseIdentifier = "CustomCell"
// More code
}
And regular cell looks like:
class RegularCell: UITableViewCell {
static let reuseIdentifier = "RegularCell"
// More code
}
The reason your dynamic cells are getting overwritten is because of the line
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
Notice that you are using the same cellIdentifier regardless of whether or not it is the custom cell or the regular cells. This means that most likely you are doing the following:
self.tableView.registerClass(RegularCell.class, forIdentifier: "new group")
self.tableView.registerClass(CustomCell.class, forIdentifier: "new group")
When you should be doing:
self.tableView.registerClass(RegularCell.class, forIdentifier: RegularCell.reuseIdentifier)
self.tableView.registerClass(CustomCell.class, forIdentifier: CustomCell.reuseIdentifier)
OR
self.tableView.registerClass(RegularCell.class, forIdentifier: "regularCellReuseIdentifier")
self.tableView.registerClass(CustomCell.class, forIdentifier: "customCellReuseIdentifier")
By using the same identifier key, you are telling the UITableView to treat both cells as the same type. So when it needs to reclaim memory for a new cell being drawn on screen, it's going to use RegularCell and CustomCell interchangeably.
Hope this helped and thanks for checking out our App!
================= EDIT =================
Realized that I forgot to add the indexIsForCustomCell method. Here it is:
func indexIsForCustomCell(indexPath : NSIndexPath) -> Bool {
if self.myData.count > 0 {
return indexPath.section == 0 && indexPath.row == (self.myData.count+1)
}
return indexPath.section == 0 && indexPath.row == 0
}
It's pretty simple. You just need to tell the tableView to expect one more cell than what is in your data source.
Example
In your numberOfRowsInSection method, you will have something like this:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count + 1 // Add one for your custom cell
}
Then in your cellForRowAtIndexPath method you just need to add some custom logic for that indexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
if indexPath.row < myData.count {
// configure cell as normal
} else {
// Add your custom cell logic here
}
return cell
}

Retrieving Information from Specific UICell Using Swift

In my program, I have an UITableView and I need to access a label in one of the UITableViewCells. I have the indexPath for the UITableViewCell, but I was wondering how I should proceed in grabbing the cell's label using Swift. Any ideas on how you access a cell without being in the table view swift file?
You shouldn't go through the cell to grab the content of the label. Instead, you should go through whatever data structures that you used to set that label in the first place.
Go to your tableView:cellForRowAtIndexPath: code, and find the part where you set up the label in the cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.items[indexPath.row] // <<== HERE
return cell
}
You have code similar to the above, where you use the source of data to set up your label from an indexPath. Using the same code to obtain the text that went into your label provides the most direct way of getting the data.