editingStyleForRowAtIndexPath Scrolling problem - iphone

I am facing a very strange problem with editingStyleForRowAtIndexPath method. I am planing to change the appearance of editable cells. It was working fine, but when i scroll the table i am not getting the table cell pointer in the editingStyleForRowAtIndexPath delegate method. So the new cells does not get the custom appearance.
I am using this -
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
// get tablviewcell pointer
UITableViewCell* pCell = [tableView cellForRowAtIndexPath:indexPath]; // <- not getting the pointer when scrolling the table and new cells come up
//Changin cell appearance here ...
}
Thanks in advance!

I think the table view may call this method before it assigns a cell to the given index path. A more reliable way to customize table view cells would be to override -tableView:willDisplayCell:forRowAtIndexPath:. You can test the cell's editingStyle property there and act accordingly.

Related

number of cell returned in uitableview

If we return 100 in numberOfRowsInSection like
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 100;
}
then how many cells will be created at a time in cellForRowAtIndexPath method?
If you are asking how many times the -tableView:cellForRowAtIndexPath: method would be called, the answer is it would be called as much cells are visible for the moment. When you scroll, it would be called for each new cell which is about to be displayed. How does it knows how many cells are visible right now? The -tableView:heightForRowAtIndexPath: is called for each cell to calculate the contentSize of the table view.
Actually it wont allocate all the 100 cells. Instead only those which will be visible at the moment. As we are using [tableView dequeueReusableCellWithIdentifier:cellIdentifier];, the cells are reused for memory handling.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
just returns the total number of cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
this method will be called each time you scroll a table view.
It depends on your cell type. If you set dequeueReusableCellWithIdentifier, then it initializes only what you see on the screen and when you are scrolling it will scroll down to the amount of rows you set in the method above.
It will allocate all 100 Cells but visible at a time only the Cells which will be fixed as per
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
height of the Cell and width of the UITableView Frame
The number of cell return its base on UITableView height. means it return number of cell display at first time. tableView:cellForRowAtIndexPath method call for only visible cell it is not call for invisible cell of UITableView. if you scroll then tableView:cellForRowAtIndexPath reuse previous invisible cell rather then cerate new one.
Agree with #pbibergal, if you are used dequeueReusableCellWithIdentifier and put a condition like below then at a time approximately nine(9) cell created at a time (number of cell is depend on tableview height). otherwise 100 cell created by system at a time.
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[MainCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if you used above code then at a time limited cell created at a time (nine cell) other wise 100 cell created at a time and it was affected in memory.

UISegment Control in UITableView

I have added a segment control to my table view and what my problem/question is I need to display text in tableview cells based on segment selected.
I have followed some tutorials, in that they gave me text in labels based on segment selected. I used segmentControl.selectedIndexPath also. So can anyone tell me how can we set that array of objects to my tableview cells based on segment selected?
Correct me if any mistakes in my english.
Please help me.
Thanks a lot for help.
First of all you have to divide your data in different arrays depends on your requirement ie Number of segmentControl.
Here if there are three segment controls then create three array an in the table view's delegate methods depending on segment control's selected index change the array to display in table view.
Like if segmentControl.selectedIndex == 0 then array1 if == 1 then array2 and if == 2 then array3.
In all delegate and datasource methods of table view. And on segment control's selecedIndexChange: method call reload table.
Happy Coding :)
EDIT 1
For change data in table view on segmented control's index change you must have one IBOutlet for tableView and use that IBOutlet to change the data using [tableView reloadData]; here tableView is IBOutlet for table view.
Happy Coding :)
Common use for tableview;
In Controller you have an array which has the objects, lets say _tableObjects
You have implemented in your controller datasource methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =......
.................
cell.labelText.text = [_tableObjects objectAtIndex:indexPath.row].name;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _tableObjects.count;
}
So if it is like this, you can change _tableObjects array in somewhere in you code.
_tableObjects = myOtherArray;
[self.tableView reloadData];

Redrawing UITableViewCell when entering/exiting edit mode

I have a table view in which the cells are built differently depending on whether the table is editing or not. Specifically, the selection style is none when in edit mode and blue when not in edit mode.
When I transition from one to the other, I noticed that some of the cells are not updated. A quick bit of logging tells me that even though the cells' appearance changes quite drastically (accessory views are added/removed correctly for example) the table view does not refresh the selection style (nor for that matter the text).
What is going on here? Are only some attributes of the cell updated when setEditing is called? Presumably only those with a specific method allowing allocation of a separate view style (for example the EditingAccessoryType)? I guess I would benefit from a EditingSelectionStyle.
How should I resolve it? By customizing setEditing to change the selectionStyle for each cell? I'm not even sure how I would iterate through the table view to do this. reloadData isn't an option because of some animation that I am using.
I found that customizing setEditing: to iterate through the visible cells and setting the selectionStyle for each to work ok.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
for (UITableViewCell *cell in [self.tableView visibleCells]) {
NSIndexPath *path = [self.tableView indexPathForCell:cell];
cell.selectionStyle = (self.editing && (path.row > 1 || path.section == 0)) ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleBlue;
}
}
If you look at the UITableViewDelegate documentation you will see a that there are five methods to customize the editing behavior. There is also the method
- (BOOL)tableView:(UITableView *)tableView
canEditRowAtIndexPath:(NSIndexPath *)indexPath
in the UITableViewDataSource documentation that will be called on each cell before you go into editing mode. The same is true for
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
that will get called for all cells that are editable. If you want to change the way the cells look you could do it in either of these. (Not implementing canEditRow.. assumes all rows are editable.)
Also note that there may be other ways to enter editing mode such as swiping on a cell, in which case
- (void)tableView:(UITableView *)tableView
willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
will be called for the cell that you swiped on:
When entering this "swipe to delete" editing mode, the table view sends a tableView:willBeginEditingRowAtIndexPath: message to the delegate to allow it to adjust its user interface.
This works on Swift 2.3, just overwriting the setEditing method in your custom cell subclass:
class MyCell: UITableViewCell {
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
//Place your code here...
}
}

problem in cell.accessoryType in UITableView

In my app if user press on any cell in UITableView then accessoryType of cell will be set to check mark like following
-(void)Check:(UITableView *)tableView Mark:(NSIndexPath *)indexPath
{
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
buttonCount++;
[selectedCellArray addObject:indexPath];
}
and if user press the same cell then uncheck will happen as follows
-(void)UnCheck:(UITableView *)tableView Mark:(NSIndexPath *)indexPath
{
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
buttonCount--;
if (buttonCount == 0) {
[selectedCellArray removeAllObjects];
}
}
and i am calling this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[self UnCheck:tableView Mark:indexPath];
}
else
{
[self Check:tableView Mark:indexPath];
}
Problem is when i am pressing on 1st cell it call Check method and mark the cell to but when i am scroll down i find 2-3 more cheked cell ...even i did not select those cell...i dont know why and how it checked automatically ...
i hope some one know where is the problem
thank you very much
Because cells will be reused by the tableview. Also set the checkmark/accessory type in your tableView:cellForRowAtIndexPath: method.
ya.. I see this happen a lot.
the correct pattern to manage the UITableViewCell state is NOT to directly manipulate the TableViewCell to update the UI, and always set, draw and create the correct state from cellForRowAtIndexPath (or tableView:willDisplayCell:forRowAtIndexPath:)
Meaning, if the user clicks on the cell and you need to update the UI of that cell, store the new state of that cell in an array or dictionary (I find that an NSMutableDictionary with the NSIndexPath as the key works very well).
then call the reloadRowsAtIndexPaths:withRowAnimation: or just [tableView reloadData] so that the cellForRowAtIndexPath reads that array or Dictionary and correctly draws the cell.
otherwise, the cellForRowAtIndexPath will constantly overwrite your changes and use recycled cells that hold incorrect state.
one exception to this rule would be if you would like a nice animation between the two states... if that is the case, save off your new state, perform your animation right there on the cell, then when the animation completes, call the same reloadRowsAtIndexPaths:withRowAnimation or reloadData so that the cell is redrawn in its new state.

How to get the cell object in tableView:(UITableView *)tableView heightForRowAtIndexPath function?

I wand to know the content of the cell when returning the heightForRowAtIndexPath. In this function how do I get the cell object?
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
}
If I try this
[tableView cellForRowAtIndexPath:indexPath]
it fails and goes off in an infinite loop.
Any idea?
Call self (the delegate) rather than the tableView itself.
id cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
Use: func dequeueReusableCellWithIdentifier(identifier: String) -> AnyObject? of UITableView.
Don't use: func dequeueReusableCellWithIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath) -> AnyObject
Possible Reason: heightForRowAtIndexPath gets called before cellForRowAtIndexPath and this method uses the index path to perform additional configuration based on the cell’s position in the table view. But since, there is still no cell yet, hence it goes to infinite loop I think.
The cell hasn't been created when heightForRowAtIndexPath: is called, so there's no way to "get" a cell. Instead, look at your model and determine the height of the cell that way.
If you're concerned about long strings and needing more vertical space in your cell, consider using sizeWithFont:forWidth:lineBreakMode:. Docs here: https://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html
I don't think you can or you should.
You'll need to determine from indexPath which data you will be displaying in the corresponding cell and thus calculate the needed height of the cell.
So you'll need to write some code to get from indexPath to the right data in your data model.
uitableviewcell *ce=[self.view viewwithtag:indexPath.row];
it returns the cell object.