Add cells to uitableView Like Mail.app - ios

I want to add cells into UItableView like in mail.app on ipad. In my cells I have UITextFields, and I have change this method to set focus
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath{
NSLog(#"%d",newIndexPath.row);
UITextField* field = (UITextField *) [tblView viewWithTag: newIndexPath.row];
int l_cellNum = field.tag;
if(l_cellNum == 1 && isAddedNewRow == FALSE){
isAddedNewRow = TRUE;
[cellsArray insertObject:#"CC" atIndex:1];
[cellsArray insertObject:#"BCC" atIndex:2];
CGRect tvbounds = [tblView bounds];
[tblView setBounds:CGRectMake(tvbounds.origin.x,
tvbounds.origin.y,
tvbounds.size.width,
tvbounds.size.height)];
NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *path2 = [NSIndexPath indexPathForRow:2 inSection:0];
NSArray *indexArray = [NSArray arrayWithObjects:path1,path2,nil];
[tblView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop];
[tblView reloadRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}
[field becomeFirstResponder];
}
But when I click to one of the cell i add 2 cells (like mail.app) but my tags for textFields do not updates, and I cant to set focus on it =(. If I call reloaddata method it calls -cellForRowAtIndexPath with this new cells at the beggining and after for all cells, and it will not work too.

It sounds like what you're looking for is a built-in style of cells called UITableViewStyleSubtitle, where you can customize the subtitle just like the iPad Mail.app. Take a look at this page in the iOS documentation. Then, you can set the subtitle of the UITableViewCell to the text that you need.
Additionally, the iOS doc has more information about customizing table view cells.

Related

UITableView ScrollToRowAtIndexPath method not working

I have a UITableView as a subview of a View. In the ViewController when the table is being populated I'm highlighting one of the rows and keeping a record of the indexPath for that row. I'm doing this in the cellforRowAtIndexPath method.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
favouriteCellView *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseID"];
QBCOCustomObject *favouriteObject = [_favouriteResults objectAtIndex:indexPath.row];
if (favouriteObject.userID == self.user.ID) {
UIView *bgColor = [[UIView alloc] init];
bgColor.backgroundColor = [UIColor colorWithRed:173.0f/255.0f green:146.0f/255.0f blue:237.0f/255.0f alpha:.5];
self.highlightedRowIndex = indexPath;
[cell setSelectedBackgroundView:bgColor];
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
return cell;
}
Then in the viewDidAppear Method I want the table to scroll to the highlighted cell.
-(void)viewDidAppear:(BOOL)animated{
[self.tableView scrollToRowAtIndexPath:self.highlightedRowIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
However I've double checked that the method is being hit with a breakpoint, but unfortunately the highlighted row is not being scrolled to the top of the table as I'd expected. AM I misunderstanding the scrollToRowAtIndexPath method? Or have I left something out of the above code.
If the row is not on screen, it will not yet be loaded by the table view. This means your cellForRowAtIndexPath for that cell will not yet be called. You'll want to choose this index in a way that does not depend on the view loading. Try this before you call scrollToRowAtIndexPath:
NSInteger row = 0;
for (QBCOCustomObject *object in _favouriteResults) {
if (object.userID == self.user.ID) break;
row++;
}
self.highlightedRowIndex = [NSIndexPath indexPathForRow:row inSection:0];

Tableview reloadData and getting CGRect of new cell

I have a UITableView with cards. Every time I want to add a new card after pushing the draw button I want it to be moved from the center of the view to the location in the table it should be placed with some basic animation. I have managed to get the destination of the new drawn card with this code:
cellRectInTableDrawnCard = [[self playerCardsTable] rectForRowAtIndexPath:drawnCardIndexPath];
cellInSuperviewDrawnCard = [[self playerCardsTable] convertRect:cellRectInTableDrawnCard toView:[[self playerCardsTable] superview]];
However, to determine the cellRectInTableDrawnCard I need to reload the playerCardsTable with reloadData but this shows the drawn card already. It is just a fraction of a second because I place the new card in the table with an animation which fires just after the reloadData. Doing a reload after the animation is not an option, because I don't have the drawnCardIndexPath then.
Is there a way I can get the rect without reloading the tableview? Or else, is there a way I can hide the new cell after reloadData and show it after the animation is done?
Thanks!
You probably want to insert the row and populate it individually and not do a complete table reload.
The code snippet shows a button that uses insertRowsAtIndexPaths:indexPathArray to add a new row which gives you the cell rect to do you animation stuff.
When you're done with animation just use reloadRowsAtIndexPaths to populate the cell value (show you're card I'd guess).
Use a bool to decide in cellForRowAtIndexPath when you should display the new card (basically after you call reloadRowsAtIndexPaths).
- (IBAction)butAddCardToHandAction:(id)sender {
// Add a blank record to the array
NSString *strCard = #"New Card";
_showCard = NO;
[_arrayHandCards addObject:strCard];
// create the index path where you want to add the card
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(_arrayHandCards.count - 1) inSection:0];
NSArray *indexPathArray = [NSArray arrayWithObjects:indexPath,nil];
// Update the table
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
// Ok - you got a blank record in the table, get the cell rect.
CGRect cellRectInTableDrawnCard = [[self tableView] rectForRowAtIndexPath:indexPath];
NSLog(#"My new rect has y position : %f",cellRectInTableDrawnCard.origin.y);
//Do the animation you need to do and when finished populate the selected cell
_showCard = YES;
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
Code to control whats displayed in cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Set up the cell and use boolean to decide what to show
NSString *strToDisplayInCell;
if (!_showCard)
{
strToDisplayInCell = #"";
}
else
{
NSString *strToDisplayInCell = [_arrayHandCards objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
cell.textLabel.text = strToDisplayInCell;
}
return cell;
}

Callback for cellForRowAtIndexPath?

My Project:
I have an UITableView in My project. Each and every UITableViewCell have one UITextView as a subview. When user tap on 'Add' button, I need to add one more UITableViewCell with UITextView to UITableView and I have to set focus into the added UITextView.
What I've Tried:
Once user tap on add button, I will update the numberOfRowsInSection of UITableView and subsequently I'll call [UITableView reloadData] to invoke [UITableView cellForRowAtIndexPath]. Here, I'll append the UITextView as subview of UITableViewCell.It Works fine until this point.
My problem:
I need to set focus into the UITextView Once after the [UITableView cellForRowAtIndexPath] get called. When I called the set focus method for UITextView after [UITableView reloadData], It is not working. I want to know, Is there any callback method for [UITableView cellForRowAtIndexPath]?
Thanks for your answers.
Try this,
In Add button action
//Assuming only 1 section, if you have more section find sections by `numberOfSections` method
NSInteger totalRows = [self.tableView numberOfRowsInSection:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:totalRows inSection:0];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
//If you have custom cell
CustomCell *cell = (CustomCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[cell.textView becomeFirstResponder];
//If you are not using custom cell, then set tag to textView and
//UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//UITextView *textView = (UITextView *)[cell viewWithTag:kTextViewTag];
//[textView becomeFirstResponder];
after you have called your reloadData method you can do something like this:
To get a reference to the last row in the last section…
// First figure out how many sections there are
NSInteger lastSectionIndex = [self.myTableView numberOfSections] - 1;
// Then grab the number of rows in the last section
NSInteger lastRowIndex = [self.myTableView numberOfRowsInSection:lastSectionIndex] - 1;
// Now just construct the index path
NSIndexPath *pathToLastRow = [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex];
//Grab a reference of your cell from the last row
MyCustomCell *myCC = [self.myTableView cellForRowAtIndexPath:pathToLastRow];
//Use this cell reference to set focus to your UITextView
[myCC.myTextView setFirstResponder:YES];

how to access tableview cell

i have a menu that contain 6 cells 1st one contain UIViewController the second contain UITableView
when i click the first cell a new page appear,and it contain a button
when i click this button i want access to the second cell from the Menu, that contain a tableView
// use this code for to Refresh or delete or insert TableviewCell
// reloading cell
NSIndexPath *tmpIndexpath=[NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:tmpIndexpath, nil] withRowAnimation:UITableViewRowAnimationTop];
// inserting cell
NSIndexPath *tmpIndexpath=[NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:tmpIndexpath, nil] withRowAnimation:UITableViewRowAnimationTop];
// deleting cell
NSIndexPath *tmpIndexpath=[NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:tmpIndexpath, nil] withRowAnimation:UITableViewRowAnimationBottom];
As much i understand your question you want to move from a tableview to other view on click..So,you have to use code similar to this..
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Detail *img1=[[Detail alloc]initWithNibName:#"Detail" bundle:Nil];
img1.labelString = [titleArray objectAtIndex:indexPath.row];
[self presentViewController:img1 animated:YES completion:nil];
}
Write following coed in your UIButton Tapped Method.
-(void) ButtonTapped:(UIButton *) sender
{
NSIndexPath *indexpathNew = [self.tblView indexPathForCell:(UITableViewCell *)[sender superview]];
NSLog(#"%#",indexpathNew.row);
}
indexpathNew is return indextPath of selected button of cell.
Try my code i might be helpful to you.

Add cell/data to the top of UITableView

I'm trying to create a simple chat application for iOS. It currently looks like this:
I want to change the order that the messages is displayed, i.e. display the latest message over the older messages. My current implementation looks like this:
// Datasource for the tableView
messages = [[NSMutableArray alloc] init];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[...]
// messageTextView is a contentView subView.
messageTextView.text = [messages objectAtIndex:indexPath.row];
[...]
- (IBAction)sendMessage:(id)sender
{
[messages addObject:messageField.text];
messageField.text = #"";
[self.tableView reloadData];
/*
I have tried the implementation below, but I always got an exception.
[self.tableView beginUpdates];
NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSArray * indexArray = [NSArray arrayWithObjects:path1,nil];
[self.tableView insertRowsAtIndexPaths:indexArray
withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
*/
}
Any tips on how to do this would be great.
Thanks.
Simple you need to insert the new UITableViewCell at the 0 index. Also modify your Datasource otherwise your app will crash. Below I show how to modify your UITableView. Modifying your datasource is easy.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
What you are essentially doing here is inserting the new chat message cell at the 0th index position. You could use a nice animation effect to make it appear or fade in.
There are various animations that you can use here-
UITableViewRowAnimationBottom
UITableViewRowAnimationFade
UITableViewRowAnimationMiddle
UITableViewRowAnimationNone
UITableViewRowAnimationRight
UITableViewRowAnimationTop
You can try.
[messages insertObject:messageField.text atIndex:0];
instead of [messages addObject:messageField.text];.
Swift Solution
Define array like this
var arrMessage = [AnyObject]()
and Button Action
#IBAction func btnSendMessageTapped(sender: AnyObject) {
arrMessage.insert(txtTypeMessage.text!, atIndex: 0)
txtTypeMessage.text = ""
self.tblMessage.reloadData()
}

Resources