Manipulating data through table view cells iOS swift - ios

firstly thank you in advance for any help and secondly I am very new to do the iOS development and swift so please bear with me and forgive me if I ask any stupid question.
MY ISSUE:
I created a table view and created an array of numbers. I iterated through the array and displayed each number in the array in a different table view cell. Now what I want to do is either have a button my table view cell or a check mark. And when ever I tap the button or the check mark the number that is being displayed on the table cell from the array is selected and then I tap another button or a check mark on a different cell and that number also gets selected and when I click the "done" button the both numbers are added and displayed on my root view.
Its kind of like a order taking app you can think of each cell as displaying the price of a food item and you can selected multiple food items and once you click done it adds up the price and displays it.
Im not looking for any advanced techniques, anything that can help me do this will be much appreciated. Again sorry for any stupid questions and thank you.

This is how you should break it down:
1) Implement the didSelectRowAtIndexPath delegate method after the table has been populated:
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
2) Within that method set the checkmark for the row:
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
3) Declare a class Array:
var numberArray: [Int]
4) Finally, implement an array extension for the addition. Call it when tapping the done button:
How can we create a generic Array Extension that sums Number types in Swift?
There's some fine tuning depending on your implementation but I hope this gives you a head start.

Key things to look at:
UITableView has a var called allowsMultipleSelection. You want to set that to true (it's false by default.)
If you want to change the way a cell looks when it is selected, then you can either look into the table view's delegate didSelectRowAtIndexPath and didDeselectRowAtIndexPath. Or if you have your own subclass of UITableViewCell, you can override the setSelected:animated: method.
The basic idea is to give the user a button to say when (s)he is done selecting cells, then look at the tableView's indexPathsForSelectedRows to find out which items were selected.

Related

Swift Button That Outputs UICollectionView Cells One by One?

I made a UICollectionView, and everything is working. It makes 100 cells that I can scroll through in simulator with no problem.
However, rather than seeing all the cells at once, I want the cells to be released one by one whenever that red button is pressed.
I am confused because I noticed in the storyboard, it hard codes the number of cells it has on the screen at once. Is there any way to get around this?
Thank you!
This is what the UI looks like in storyboard.
This is the code I used to make it. It's basic, and just says to fill the text box of the cell with a string from the array.
Your question is garbled.
A collection view has a delegate and a data source. The data source responds to messages in the UICollectionViewDataSource protocol. That protocol lets the collection view ask how many sections it has, and how many rows in each section, as well as asking for the cells from those sections and rows.
There are also methods that let you tell the table view that you want to add more cells. Take a look at the method insertItems(at:). That lets you provide an array of indexPaths, which tells the table view that you have added new entries.
You could certainly write a button action method that added one or more entries to your data model and then used the insertItems(at:) method to notify the collection view that it had new entries. If there was room in the content view of the collection view to display additional cells it would then call the data source and ask for new cells at those index paths.
Sounds like you just need to keep track of how many items you want displayed (which will increase the more that button is pressed) and use that in your UICollectionViewDataSource method. Something like:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return min(myRunningItemCount, maximumNumberOfItems) //assuming there's a maximum
}
Then you just need to call reloadData on the collection view whenever that number changes.

Select not visible cell inside a collection

Well, one might ask why should you do that ?
I have a collection view inside some view where the user can select a cell.
Then this selection is saved and later, when the user wants to enter that view again, he should be able to see his previous saved selection.
If his selection was at the end of the collection view, I will not be able to load the collection view with his previous selection, because:
for cell in collectionView.visibleCells()
// find and select previous cell
Will not loop through all cells, specifically the one the user chose (that does not exist yet).
Is there a solution to this problem?
You can remember the exact index paths of selected rows (using indexPathsForSelectedRows), but this is still not safe if your dataSource set changes/updates and the remembered indexes may become invalid with new/different set of data. Thus you should remember selection of “real world” objects (where you're filling specific cell data, like title etc.) for example by remembering object identifiers of your choice so you'll be able to re-map and re-select rows in case of reload with different data. The management of objects selection is generally completely in your hands.
Well after a lot of searching, what works for me is to set a local variable say: selectedCell , then when I want to show a previous user selected cell, i will just set the variable , and on :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
if(indexPath.row==selectedCell)
}
I am checking if its already selected and mark it .
I could not find any other clever way of doing so automatically .

How to have DidSelectRow activate keyboard?

Goal
I want to have a keyboard (custom) to show when I click on a cell in my tableview and have said keyboard edit a label in the selected cell.
What I have read and tried
Stack overflow and other searched threads/tutorials
A Swift example of Custom Views for Data Input (custom in-app keyboard)
How to make custom keyboard only for my app in Swift?
iOS 8: Creating a Custom Keyboard in Swift
Along with other results and searches (also the recommended readings within these threads), these were great for me getting the keyboard the way I want it (which is app-specific, I don't want to have the user install the keyboard to use the app), however, none explain how I could "activate" the keyboard without a textfield.
My thought process is this: I will have a keyboard with a textfield in place in order to receive the input from the keys pressed. This input would then be sent to the label that is in the selected cell. The problem is in the keyboard showing without anything to call it...
Why I don't want a textfield in the cell: Because I think it is more smart/elegant to have the tableview cell activate the keyboard. I have seen this in other apps and I can't figure out how it is done.
Any help on this matter is much appreciated. I am completely new to programming, am using Swift (so have no clue Obj-C or the like).
Thank you!
Well after a lot of discussions around other websites, it is a shame to say it but what I wanted was actually impossible (like stated by Duncan). For some reason I thought that in programming that word did not exist, but alas it is there. Well, the way that I did work around this limitation was as replied here in the comments as well as from the resource materials I already read:
I have 2 views:
tableView - this will have the list of items that I would like to edit a value. Has multiple labels where one of them would be edited by the user.
keyboardView - custom keyboard that would allow user input.
For the keyboard I used the delegate method as described in "A Swift example of Custom Views for Data Input". This worked perfectly and would send the data over to the tableView under the keyWasTapped function.
Next was the tableView. I had 3 labels in the custom cell, where one was called valueLabel. I had to add a textField to my storyboard hidden behind the tableview with which the user will interact and in the didselectrow I included the command to summon the keyboard:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
textField.becomeFirstResponder()
}
From there I would grab the text from the textfield and update the UILabels in my custom cell. At least this way I can select a cell and not the textfield. So considering that the answer that would fit what I wanted is combination of the replies, I thought it would be best to say it here.
Thanks to Sandeep and Larme for their time.
TVDN,
Have a textField in cell not the label :) Create a custom cell create an IBOutlet to that class ffrom textField in cellForRowAtIndexPath
let tableCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! myCell
tableCell.yourTextField.resignFirstResponder()
and in didSelectRowAtIndexPath
let tableCell = self.tableView.cellForRowAtIndexPath(indexPath)
self.tableView.dequeueReusableCellWithIdentifier("cell") as! myCell
tableCell.yourTextField.becomeFirstResponder()

How to read data/test from each row of a UITableView?

In my iOS app the user is supposed to fill in all fields in a table where each row may contain a:
a text view, or
a date picker or
a picker view, or
a switch.
I have created 7 different types of cell each of which contains one of those UI components with its specific tag. In this way I can access them when the table is only in "read mode".
The last row of the cell contains a "Save" button. When pressed, all these values should be collected together into an object which will be stored in a database.
The problem is that I don't know how to read those things from each row.
Is there a specific method?
To get all data from your cells best way would be to have an NSArray that will have all the data you need, and update these values in NSArray for corresponding data in the cells. You have to use some kind of dataSource to show the data in the tableView and you can use that exact NSArray to update values and on save to simply go through it and save these values.
For the other questions:
#NickCatib 1) I don't understand what the method func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) does. Is it used to get data from each cell? When is it called? (in other words how can I link it to the IBAction of the submit button)
That method is called when you select particular cell. You can link it with selectRowAtIndexPath:animated:scrollPosition: method.
#NickCatib: 2) is it better to assign to each cell an unique tag to read the data when the submit button is touched?
You can, but again, better way would be to iterate thourgh NSArray as mentioned above.

Create nested table view or separate page?

I'm trying to create an options page for my iOS app. I have an array of categories like this:
var options = [
"Location",
"Calculation Method",
"Juristic Method",
"Manual Adjustment",
"Daylight Saving Time"
]
Then I am loading them up in my view controller like this:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return options.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .Default, reuseIdentifier: "Cell")
cell.textLabel?.text = options[indexPath.row]
return cell
}
This give me a single table view perfectly! Now I'm trying to handle the click of each row to bring up a list of options for that category. For example, the Location will have a switch to enable GPS or allow them to select their location drop downs or a map. Calculation Method will bring up a table view of check marks. Daylight Saving Time will bring up a single row with a switch.
My question is what is the best approach for all this? Should I create a dictionary of arrays to hold my options and reuse the table, or should I create a separate view for each category of options? I'm finding conflicting or outdated tutorials on this and I'm also having trouble converting examples from Objective-C. Any help or direction would be greatly appreciated!
I'd suggest creating separate views for each category of options. From your example above, you'd end up with 5 more view controllers: Location, Calculation Methods, Juristic Method, Manual Adjustment, and Daylight Saving Time. And then for your Calculation Methods, since it's a table view of check marks, I'd probably have an array that stores each option inside the CalculationMethodsViewController. Same for the others. If they need other data to display, put it in the new view controllers - not in your original view controller.
For your top level of categories, I'd suggest using the sections of a tableview to separate things. Then each row in a section would correspond to the detailed option.
To do this, you could have an array of 'categories' that are to keep the order of sections. This would match the options array you've defined in your question. Alongside this, I would put a Dictionary of sub-category options. For Locations it would look like this:
var options = [
"Location" : ["location-enable-gps", "location-choose-list", "location-choose-map"],
"Calculation Method": ...,
"..."
]
In the above Dictionary, the array values for Location are constants that I've defined. This is because you will be changing the behavior of each cell drastically. Enable GPS can just be a checkbox, Choosing from a list may be better to drilldown/modal (and when selected display selected location), choosing from map may also lend itself to a modal design ("Modal" is when a view controller pops up and then dismisses after an action).
Let me know if this all makes sense, it looks like your options will be very diverse, so unfortunately I don't think there is one method (drill down, collection view) that works best. That being said, its all up to you on how you want your users to experience your app.

Resources