I am trying to sync a UITableView with a UILabel to make sure they show the same data; of course, things will be different in the end, but for testing this is what I need to do.
See the arrow? I want that middle cell (from px44-88) to show the cell.textLabel.text in a UILabel when it is the "middle cell".
I tried using - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath but I was having so many problems I figured I'd come here to ask if anyone has a better way of doing this. I'm not sure if it would make a difference or not but I am using NSFetchedResultsController to populate my UITableView.
UITableView is a subclass of UIScrollView, so probably you can use UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
member to detect which cell is currently in the middle.
I.e. assuming you have a plain table with no sections, and tableView is an outlet for the table, label is an outlet for the label, than this will function in your controller will work:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
int row = (scrollView.contentOffset.y + tableView.frame.size.height / 2) / 44;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
label.text = cell.textLabel.text;
}
Of course, you need to do some scrolling to make it work ;)
You can use visibleCells method to get layout of visible cells for non-plain table and use it to detect cell in the middle of the table.
Related
I want to do min/max (expand/collapse) button functionality.Please see bellow image for more information.Is anybody know how to develop this functionality.I have some examples but those are not like exactly what i want.Please help me to solve this problem.
I've got a similar kinda requirement few days back. I have done this using custom tableview cell.
Firstly, you have to pass the indexpath of each row to the cell. For this i have taken a property in custom tableview cell.
i.e, #property(nonatomic,assign) NSIndexPath *indexPathOfCell;
Now, you have to pass the indexpath of row in datasource method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
And you have to write a delegate method in custom tableviewcell so that when the user clicks on the min/max button you can reload that cell through this delegate call.
-(void)reloadCellWithIndexPath:(NSIndexPath*)indexPath;
You have to set the view controller as delegate for the custom tableview cell in which you are populating the table. In that class you have to maintain an NSMutableArray.
NSMutableArray *selectedIndexPaths;
When ever the reloadCellWithIndexPath gets called you can simply do same.
-(void)reloadCellWithIndexPath:(NSIndexPath*)indexPath{
if(![selectedIndexPaths containsObject:indexPath]){
[selectedIndexPaths addObject:indexPath];
}else
[selectedIndexPaths removeObject:indexPath];
[tableView reloadData];
}
In heightForRowAtIndexPath method you can change the height for a particular row.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
BOOL cellModeChanged = NO;
for (NSIndexPath *indexpath in selectedIndexPaths) {
if(indexpath.section == indexPath.section && indexpath.row == indexPath.row)
cellModeChanged = YES;
}
if(cellModeChanged)
return 400.0;
else
return 100.0;
}
I am using XCode4.2 to develop a storyboard application
I am switching views based on a click in a UITableView after clicking the row is highlighted in blue and the new view is loaded .
when I come back to the original view the row is still highlighted in blue ... how can I disable that ?
I do this in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath];
}
That way I have the index path that was selected every time.
use deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated function to deselect rows in uitableview
call it in your viewWillAppear function
[yourTableView deselectRowAtIndexPath:selectedIndexPath animated:NO];
if you are not sure which is index you select last time you can run a loop on all the index path in your table.
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
for(int i = 0; i <= [yourArr count]; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[yourTableView deselectRowAtIndexPath:indexPath animated:NO];
}
}
Note: As I don't know your exact code....you need to modify above code to your needs.
A UITableViewController does this automatically. Otherwise, in your viewDidAppear for the owning controller, you need to call - (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated on the table view.
I have a TableView with a CustomCell.In my CustomCell i have some Label's and one Button when ever i am clicking on the Button some of the Label will get hide.Here comes my problem now i need to resize my UITableViewCell based on the CustomCell Height.I know using
- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath
i can resize my UITableViewCell.But how can i resize based on my custom cell height.I dont want to use any timer methods. if any one know please help me..
This is what I do to adjust a tablecell height:
I remake the cell at the desired index path and adjust the height according to it.
- (float) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.contentView.frame.size.height;
}
I need to get the NSIndexPath for a custom cell in a UITableView. Here's the problem: I send a NSNotification from my custom cell to my UITableViewController when editingDidBegin gets called from a UITextField in my custom cell. In my UITableViewController, I resize the UITableView when the UITextField began editing, and then want the table view to scroll to the Cell in which the UITextField is first responder. But I can't figure out how to return the indexPath of the cell where the UITextField is being edited. I have tried so many ways, but its still not working. One way is this: in my cstomCell class i select the row using [self setSelected:YES] and in my TV controller then if I NSLog the row of [self.tableV indexPathForSelectedRow] it always returns 0 even though its always not 0.
Just give the cell a value for its tag property. Then you can get that cell by calling this
UITableViewCell *cell = (UITableViewCell *)[self.tableView viewWithTag:tagValue];
then once you have the cell you can get the NSIndexPath like this
NSIndexPath *indexPath = [self.tableView indexPathForCell:nextResponderCell];
Since you have a UITextField in your custom cell you can place cell.textField.delegate = self; in the
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
data source method. That way you will not have to setup a NSNotification in the Custom Cell. Also in this same method you can tag both your cells text field like this cell.textField.tag = indexPath.row; and the cell like this cell.tag = indexPath.row;
Now that you have set the UITextField delegate, you can now place this method in your UITableViewController class
- (void)textFieldDidBeginEditing:(UITextField *)textField {
CustomCell *cell = (CustomCell *)[self.tableView viewWithTag:textField.tag];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
}
The above UITextField delegate method should get you the indexPath for the cell you have currently selected.
try this code..
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
UITableView *tableView;
UITableViewCell* superViewCell = [self returnSuperCellViewOfTextField:textField];
if(superViewCell)[tableView scrollToRowAtIndexPath:[tableView indexPathForCell:superViewCell] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
-(id)returnSuperCellViewOfTextField:(id)viewToCheck
{
id superView = [viewToCheck superview];
if([viewToCheck isKindOfClass:[UITableViewCell class]] && superView)return superView;
else if(([viewToCheck respondsToSelector:#selector(superview)] && superView)) return [self returnSuperCellViewOfTextField:superView];
return nil;
}
Does this (your answer that you gave before below)still works if you have multiple texfields in each cell?:
UITableViewCell *cell = (UITableViewCell *)[self.tableView viewWithTag:tagValue];
then once you have the cell you can get the NSIndexPath like this
NSIndexPath *indexPath = [self.tableView indexPathForCell:nextResponderCell];
Since you have a UITextField in your custom cell you can place cell.textField.delegate = self; in the
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
data source method. Also in this same method you can tag both your cells text field like this cell.textField.tag = indexPath.row; and the cell like this cell.tag = indexPath.row;
Now that you have set the UITextField delegate, you can now place this method in your UITableViewController class
- (void)textFieldDidBeginEditing:(UITextField *)textField {
CustomCell *cell = (CustomCell *)[self.tableView viewWithTag:textField.tag];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
I have a tableview with 8 cells, and in each cell i have 6 texfields, and also the tableview is dynamic, so the user can insert more cells...but i´m having trouble in how to save the text the user enters in each texfield. Is it possible that with "cell.textField.tag = indexPath.row", the controller identify´s the texfield i´m in?
I like to tag my cells like so:
/* Create a tag based on the section and row of a cell(used to retrive the cell for the beginEditingNextCell method. */
-(NSInteger)tagForIndexPath:(NSIndexPath*)path {
return path.section * 1000 + path.row + 1;
}
The other way is to pass the beginEditing data using a custom delegate, and include a cell model, which you can then use to figure out your path depending on how you are storing data.
Check out my github project, it has the code to handle this case, as well as resizing for the keyboard and tabbing to the next editable cell: https://github.com/andrewzimmer906/XCell
I have a couple of rows in a table view which I like to edit.
I thought that setEditing method would give me a Edit and Delete button, but it only shows a Delete button. Because I don't have a detail view controller that's going to be pushed in didSelectRowAtIndexPath I thought I could show a couple of editing elements in the selected cell.
I need to add three buttons to specify priority on assignments: Low, High and Medium priority. This means that I have to change the height of the selected cell to make room for these buttons, I think that's rather easy to do.
What I'm wondering is if this is the correct path to choose?
I have done quite a lot research today without finding examples of how other have solved editing in a UITableViewCell. If you edit a contact in the Contacts app in the iPhone the UITableViewCells changes to enable quick and easy editing, that's what I'm looking for.
So what do you have for tips for me regarding this question?
Edit #1
My code in didSelectRowAtIndexPath is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Cell *selectedCell = (Cell *)[tableView cellForRowAtIndexPath: indexPath];
UIButton *btn = [UIButton buttonWithType: UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 50, 100);
btn.titleLabel.text = #"Set this item to High Priority";
btn.backgroundColor = [UIColor greenColor];
[selectedCell.contentView addSubview: btn];
self.editing = YES;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
Code for heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell = nil;
if (self.editing)
cell = (Cell *)[tableView cellForRowAtIndexPath: indexPath];
else
cell = nil;
BOOL expandCell = NO;
NSInteger expandationHeight = 0;
if (cell != nil)
{
for (UIButton *btn in cell.contentView.subviews)
{
NSLog(#"A button was found.");
expandationHeight = 70;
expandCell = YES;
}
}
return expandationHeight + heightOfOtherElements;
}
When I click at a cell nothing happends but everything becomes disabled, I can't click any elements on the hole view. This has something to do with [tableView cellForRowAtIndexPath: indexPath], because if I uncomment that line the UI does not become disabled.
What am I doing wrong?
That's not too complicated though it requires some stuff.
You want to change the content of one cell or of all cells?
To specify a specific height for one cell, use the - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath delegate method.
It is called for each cell each time the table view is displayed. If you want to change a single row, call reloadRowsAtIndexPaths:withRowAnimation: method from UITableView. If you want to update all cells, simply use - (void)reloadData method.
You can also access a specific cell using - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath method from UITableView. Then you can reconfigure it to add various elements on it, as you want.
Thus, when a cell is selected, check whether you have to edit it or not, then :
update your cell get from cellForRowAtIndexPath
be sure your method tableView:heightForRowAtIndexPath: will return the good height
tell the table view to update the view using reloadRowsAtIndexPaths:withRowAnimation: