if the custom tableviewCell has "TextField", how it easy to map to modal property? - ios

Situation:
if there has a UITableview have 10 cell on it,
there have "UILabel + UITextField" in each cell, also have 10 modal property corresponding to each cell, Each cell is get value in different property in the modal, also user change the value in the UITextField on the cell, also update the corresponding modal properTY value
like :
value in modal.name is corresponding "section:1 row:1" cell
value in modal.age is corresponding "section:1 row:2" cell
....
question:
is there have any easy way handle this situation?
cause i dont't like to set the value one by one in method "cellForRowAtIndexPath"
like:
if (indexPath.section == 1 && indexPath.row == 1) {
cell.textFiled = modal.name;
}
also the textField value change in cell"section:1 row:1", how to update the "modal.name" easily?
Thanks

You can add two methods in custom cell class.
One is: -(void)configureCellWithModel for display data.
Another is: -(void)updateCellWothModel for update data.
Put these methods in the custom cell class.

Related

IBAction from TableViewCell triggers multiple cells

I have a UITableViewController with dynamic cells.
in my tableViewCellForRowAtIndexPath I set the indexPath.row as tag to one of my subviews from that cell. This subview has an IBAction when one clicks on it.
In my custom TableViewCell I call a listener when this subview is clicked and give the value of the tag as parameter, so that my TableViewController can act on it.
This is what I do then: (it is in java, because I am using multi-os-engine but it is very similar to swift/obj-c)
#Override
public void onOrderClicked(long index) {
OrdersTableViewCell cell = (OrdersTableViewCell) ordersList().cellForRowAtIndexPath(NSIndexPath.indexPathForRowInSection(index, 0));
if (cell.arrowView().image().equals(UIImage.imageNamed("downarrow"))) {
cell.arrowView().setImage(UIImage.imageNamed("uparrow"));
cell.orderDetailsView().setHidden(false);
}
else {
cell.arrowView().setImage(UIImage.imageNamed("downarrow"));
cell.orderDetailsView().setHidden(true);
}
Basically I just change the hidden state of one subview in my cell. Actually this works fine. BUT when clicking on one of my elements, the subview hidden state sometimes changes not only from this cell, but also from another one. I don't understand why. For more information: There are multiple cells so, that I even have to scroll to see them all. And when clicking on one of my cells, the hidden state of another cell changes too, which is not in the screen atm.
Anyone has a hint what I am doing wrong or why this is happening?

Update array data used to create UITableView when IBAction is fired

I have created a UITableView that includes a UIImage, and two UILabels. This data is passed to a details view controller when the user selects the row. I have also successfully created a UIButton in the prototype cell that updates the text of one of the UILabels. I am unsuccessfully attempting to update this label within the array so this change is reflected on the details view controller. This is what I tried with no success:
#IBAction func updateTableData(_ sender: Any) {
grinds.removeAll()
grinds = createArray()
}
Here is a link to the repo: https://github.com/andrewTuzson/tableViewPractice
In the screenshot below, the left image displays the tableview after the first cell has been toggled to "Needs Work". The right image displays the details screen that is loaded after selecting the row.
How should I approach solving this?
If you want to update a tableViewCell upon the button click then, you should make the model array global to access it in click method and update what you want then reload the tableView either with delegate or NSNotificationCenter
--
in the custom class of the cell declare an integer property and in cellForRow set it like this
cell.index = indexpath.row

Create IBAction for CollectionViewCell

I've got a collection view with multiple cells created programically. I want to update a variable to a different value when the user taps a specific cell. So eg: Cell 1 is tapped -> var test = "cell1" , cell2 is tapped var test = "cell2". Usually I'd just create an IBAction by dragging from the storyboard but I'm not sure how to do it in this case.
I'm using Swift 3.1
To add interactivity to UITableViews, UICollectionViews, and other kinds of views which display collections of data, you can't use Storyboard actions, as the content is generated dynamically during runtime, and the Storyboard can only work for static content.
Instead, what you need to do is set your UICollectionView's delegate property to an object that implements the UICollectionViewDelegate protocol. One of the methods defined as part of the protocol is the collectionView(_:didSelectItemAt:) method. This method will get called whenever the user selects (taps) a collection view cell with the IndexPath to that cell as an argument. You can update your variable in that method. Just remember to deselect the cell after handling the tap by using the deselectItem(at:) method on your UICollectionView.
There are UICollectionView delegate that you need to implement. It goes like this
did select item at index path will give index path of the cell that was selected. Using indexpath or any other property of the data source array you are using, you can modify the variable value.
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if let cell = collectionView.cellForItemAtIndexPath(indexPath) {
//check your condition and modify the variable value depending on index path or any other property you are referring to.
}
}

Simultaneously change display parameters on all table view cells

I am trying to implement a table view design where a user can click a button outside of a table view cell and the display mode of all the buttons should change. However this is not the 'selected' mode for a given cell (that will be yet a third state that becomes accessible via switching to this second state). What's the proper way to accomplish this?
I am using dequeueReusableCellWith so I don't want to simply cycle through every cell because some that are out of sight probably shouldn't be modified. I simply want any cell that is visible, or becomes visible, while the table view cell is in this second display mode to follow a second design rather than the first design.
The second design, for now, is being modified via a method I added to a subclass of UITableViewCell like so:
- (void) p_refreshDisplay {
if (self.editing) {
self.buttonToClearWidth.constant = 20;
self.buttonToClearLeadingWidth.constant = 20;
} else {
self.buttonToClearWidth.constant = 0;
self.buttonToClearLeadingWidth.constant = 0;
}
}
However, I'm not sure how to trigger this p_refreshDisplay for every visible (and to become visible) cell. It seems unwise to call this many times and refresh the table view. What would be the proper way to accomplish what I want to do?
You do what should be done for any table view change:
Update your data model or some flag as needed.
Either call reloadData on the table view or call reloadRowsAtIndexPaths:withRowAnimation: passing in indexPathsForVisibleRows as the list of rows to reload.
Implement cellForRowAtIndexPath to provide appropriate cells for the given data/flags.
It sounds like you should have a custom cell class that has one or more properties that can be set on the cell in cellForRowAtIndexPath so the cell can render itself properly based on the specified state.
You can achieve this by doing three things:
Establish some property that indicates the "mode" of the table, either a boolean or perhaps an enum if there are more than three states
Ensure that cellForRowAtIndexPath configures the cell appropriately based on the value of this property. This will ensure that newly displayed cells are configured correctly.
When the "mode" changes you can use the tableview's visibleCells property to update any currently visible cells:
for cell in tableview.visibleCells {
if let myCell = cell as? MyCustomCellClass {
myCell.setButtonStyle()
}
}

Swift 2.0, UITableView: cellForRowAtIndexPath returning nil for non-visible cells

Please don't mark this as a duplicate question because I have found no suitable answer for my query.
I have a table view with cells that contain text fields. I have a button at the bottom of the screen. The number of rows is greater than the screen can display, so some cells are not in view. I want that at any point when the button is pressed, all textfields be read and the text input be processed. I am unable to do so because apparently because of the reusability of cells, cells out of view do not exist at all and cellForRowAtIndexPath for those indexPaths gives a runtime error. I have read answers that say that this simply can't be done. But I find it hard to believe that there is no workaround to this. Please help. Thanks in advance!
This definitely can't shouldn't be done (accessing cells that are off screen, or implementing workarounds to allow it), for reasons of (at least) performance and memory usage.
Having said that there is, as you put it, a workaround. What you will need to do it change how you are storing the values in those text fields. Rather than iterating through cells and retrieving the text directly from the text fields you should store the text for each field in an collection.
Define a dictionary property on your table view controller / data source to hold the text for each row.
Act as the delegate of UITextField and assign as such in tableView:cellForRowAtIndexPath:
Implement textField:didEndEditing: (or whatever is appropriate for your use case) and store the text in the dictionary keyed against the index path relating to the cell that contains that text field.
Update the button action method to use this dictionary instead of iterating through cells.
Create a UITableViewCell subclass, add your tableViewCells a index property and introduce a delegate like:
protocol CustomCellDelegate {
func didEditTextField(test : String, atIndex : Int)
}
Create a delegate variable on your UITableViewCell subclass.
var delegate : CustomCellDelegate?
Implement the UITextViewDelegate in your tableViewCell and set the cell to be the delegate of your textfield.
Implement these two methods:
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField : UITextField) {
// call back with the delegate here
// delegate?.didEditTextField(textfield.text, atIndex: self.index)
}
So when the user ends editing the textField, your cell will call out with a delegate, sending the text and the index.
On your viewController, when you init your tableViewCell, set the delegate of the cell to the viewController, and set the index to indexPath.row .
Set up on your viewController a String array with as many items as many tableViewCells you got. Init the array with empty strings.
So you got the delegate on your viewController, and whenever it is called, you just insert the returned text to right index in the string array on your viewcontroller.
What do think, will this work?
If we can assume that cells that have NEVER been created has no text inputs, then create an Array or Set ourselves and clone the content/input texts there whenever user inputs to a cell's textfield.
Whenever, that button is clicked, you can iterate the array instead of cells to get all the inputs.
This is a bit hacky though..

Resources