In Apple\'s Messages app, when you click a correspondent\'s name and switch to the table view of the conversation (with balloons for each message), the table appears scrolle
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
CGFloat labelWidth = 260.0f;
CGFloat labelRequiredHeight = 180.0f;
@synthesize tblView;
@synthesize txtField;
@synthesize chatData;
- (void)viewDidLoad
{
[super viewDidLoad];
tblView.delegate = self;
[self.tblView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
chatData = [[NSMutableArray alloc] init];
[self registerForKeyboardNotifications];
}
-(IBAction) textFieldDoneEditing : (id) sender
{
NSLog(@"the text content%@",txtField.text);
[sender resignFirstResponder];
[txtField resignFirstResponder];
}
- (IBAction)sendButton:(id)sender
{
if (txtField.text.length>0) {
// updating the table immediately
NSArray *data = [NSArray arrayWithObject:@"text"];
NSArray *objects = [NSArray arrayWithObject:txtField.text];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:data];
[chatData addObject:dictionary];
NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0];
[insertIndexPaths addObject:newPath];
[tblView beginUpdates];
[tblView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop];
[tblView endUpdates];
[tblView reloadData];
txtField.text = @"";
[self.view endEditing:YES];
}
}
-(IBAction) backgroundTap:(id) sender
{
[self.txtField resignFirstResponder];
}
-(BOOL)SendbtnShouldReturn:(UITextField *)textfield
{
[textfield resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(@"the text content%@",txtField.text);
[textField resignFirstResponder];
if (txtField.text.length>0)
{
// updating the table immediately
NSArray *keys = [NSArray arrayWithObject:@"text"];
NSArray *objects = [NSArray arrayWithObject:txtField.text];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[chatData addObject:dictionary];
NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0];
[insertIndexPaths addObject:newPath];
[tblView beginUpdates];
[tblView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationTop];
[tblView endUpdates];
[tblView reloadData];
txtField.text = @"";
}
return NO;
}
// Keyboard Functionality
-(void) registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
-(void) freeKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
-(void) keyboardWasShown:(NSNotification*)aNotification
{
NSLog(@"Keyboard was shown");
NSDictionary* info = [aNotification userInfo];
// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// Move
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
NSLog(@"frame..%f..%f..%f..%f",self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
NSLog(@"keyboard..%f..%f..%f..%f",keyboardFrame.origin.x, keyboardFrame.origin.y, keyboardFrame.size.width, keyboardFrame.size.height);
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y- keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[tblView setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+ keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height-keyboardFrame.size.height)];
[tblView scrollsToTop];
[UIView commitAnimations];
}
-(void) keyboardWillHide:(NSNotification*)aNotification
{
NSLog(@"Keyboard will hide");
NSDictionary* info = [aNotification userInfo];
// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardFrame;
[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardFrame];
// Move
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
[self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[tblView setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height)];
[UIView commitAnimations];
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.tblView.contentInset = contentInsets;
self.tblView.scrollIndicatorInsets = contentInsets;
self.tblView.scrollEnabled=chatData;
}
#pragma mark UITableViewDataSource protocol methods
- (void)scrollTableToBottom
{
int rowNumber = [self.tblView numberOfRowsInSection:1];
if (rowNumber > 0) [self.tblView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rowNumber-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [chatData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=@"chatCell";
chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier: @"chatCellIdentifier"];
if(!cell)
cell =[[chatCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
// NSUInteger row = [chatData count]-[indexPath row]-1;
NSUInteger row=[indexPath row];
NSUInteger count = [chatData count];
if (row <chatData.count)
{
NSString *chatText = [[chatData objectAtIndex:row] objectForKey:@"text"];
cell.txtMsg.text = chatText;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [[chatData objectAtIndex:chatData.count-indexPath.row-1] objectForKey:@"text"];
UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:20.0];
CGSize constraintSize = CGSizeMake(225.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 40;
}
//-(void)scrollToBottomTableView
//{
// if (self.tblView.contentOffset.y > self.tblView.frame.size.height)
// {
// [self.tblView scrollToRowAtIndexPath:[self. indexPathForLastMessage]
// atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// }
//}
-(void)viewWillAppear:(BOOL)animated
{
// [tblView reloadData];
//
// int lastRowNumber = [tblView numberOfRowsInSection:0] - 1;
// NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0];
// [tblView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
-(void)viewDidAppear:(BOOL)animated
{
//[tblView reloadData];
}
- (void)reloadTableViewDataSource
{
[tblView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
I'm using autolayout and none of the answers worked for me. Here is my solution that finally worked:
@property (nonatomic, assign) BOOL shouldScrollToLastRow;
- (void)viewDidLoad
{
[super viewDidLoad];
_shouldScrollToLastRow = YES;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Scroll table view to the last row
if (_shouldScrollToLastRow)
{
_shouldScrollToLastRow = NO;
[self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
}
}