UITableView mess up after resizing | Objective-C - ios

I'm using a TableView to create a chat app. Where each cell represent a msg. The cell height change based on the contents of the msg.
For example if its a photo it will have a fixed size.
If its a text it will have a size depend of number of line in msg.
Also the whole TableView change size when the user try to send a msg based on the size of the keyBoard appeared.
The problem is that when the tableView size changes, the tableView cells get messed up!
This only happen when is scroll down (re-render the cells that disappear)
Update: This happened also if some of the cells where invisible (big tableView). before the re-sizing. And also it does not have anything with the type. Because it does the same if the msgs are all text
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[[msg objectAtIndex:indexPath.row] objectForKey:#"type"] isEqualToString:#"msg"]) {
int numberOfline= [[[msg objectAtIndex:indexPath.row] objectForKey:#"line"] intValue];
return topMergeH + topBubbleH + bottomBubbleH + bottomMergeH + (bubbleHieght*numberOfline);
}
else
return topMergeH + topBubbleH + bottomBubbleH + bottomMergeH + bubbleHieght + 220;
}
- (void) changeTextFieldPoistion {
//TextFieldHight = 30
[_typeRef setFrame:
CGRectMake(0,self.view.frame.size.height-keyBoardHeight-30
, _typeRef.frame.size.width, _typeRef.frame.size.height)];
[_myTableView setFrame:
CGRectMake(_myTableView.frame.origin.x, _myTableView.frame.origin.y
, 374, self.view.frame.size.height-_myTableView.frame.origin.y-keyBoardHeight-30)];
}
Pic1: Before Re-sizing
Pic2: After Re-sizing 1

I found the answer here
The problem was with the Cell Identifier
Before Code:
static NSString *simpleTableIdentifier = #"ChatSendTableViewCell";
ChatSendTableViewCell *cell =
(ChatSendTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:simpleTableIdentifier owner:self options:nil];
cell = [nib objectAtIndex:0];
}
After Code:
static NSString *CellIdentifier1 = #"ChatSendTableViewCell";
UITableViewCell *cell;
if (indexPath.section == 0)
{
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
}
}

1 - when keyboard Appers Get keyboard size -
keyboardInfo = [notification userInfo];
kbSize = [[keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
2-if your chatTable Contains Any row -
whwre [messageList] is Number of Rows
if ([messageList count]) {
NSIndexPath *iPath = [NSIndexPath indexPathForRow:[messageList count]-1 inSection:0];
UITableViewCell *lastCell = [chatTable cellForRowAtIndexPath:iPath];
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, lastCell.frame.origin) ) {
CGRect bkgndRect = lastCell.superview.frame;
bkgndRect.size.height += kbSize.height;
[lastCell.superview setFrame:bkgndRect];
[chatTable setContentOffset:CGPointMake(0.0,(lastCell.frame.origin.y+lastCell.frame.size.height) - (kbSize.height)) animated:NO];
}
}

Related

Set UITableViewCell in full screen

I want to set UITableViewCell in full screen when user select cell with bouncing animation. I shared link below. I want same like this.
https://drive.google.com/open?id=0B9k_Shyb5v62eFdxWXhYeXV3a0E
I set view inside cell. But I can't set it in full screen with animation.
Below is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableViewList cellForRowAtIndexPath:indexPath];
int index = [cell.accessibilityIdentifier intValue];
CGFloat delay = 0.0f;
if (indexSelected == (int)indexPath.row)
{
//COLLAPSE
indexSelected = -1111111111;
UIView *viewController = (UIView *)[cell.contentView viewWithTag:TAG_DETAIL_CONTROLLER];
[viewController removeFromSuperview];
tableViewList.frame = frameTableViewList;
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
btnBack.hidden = YES;
indexSelected = -1;
}
else
{
//EXPAND
if (indexSelected < 0)
indexSelected = index;
else
{
int indexPrevious = indexSelected;
indexSelected = (int)indexPath.row;
[tableView reloadRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:indexPrevious inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
delay = 0.3;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
CGRect frame = tableViewList.frame;
frame.origin.y = 0;
frame.size.height = CGRectGetHeight(self.view.frame);
tableViewList.frame = frame;
btnBack.hidden = NO;
});
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
cell = [self reuseTableViewCellWithIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *viewController = (UIView *)[cell.contentView viewWithTag:TAG_DETAIL_CONTROLLER];
if (indexSelected >= 0 && indexSelected == (int)indexPath.row)
[self addDiamondDetailView:cell index:(int)indexPath.row];
else
{
if (indexSelected == -1111111111)
{
CGRect frame = cell.frame;
frame.size.height = cellHeight;
cell.frame = frame;
cell.contentView.frame = CGRectMake(0, 0, CGRectGetWidth(cell.frame), CGRectGetHeight(cell.frame));
}
[viewController removeFromSuperview];
}
cell.contentView.clipsToBounds = YES;
return cell;
}
- (void)addDiamondDetailView:(UITableViewCell *)cell index:(int)index
{
DetailVC = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
DetailVC.selectedStoneInfo = (StoneInfo *)[arrStone objectAtIndex:index];
DetailVC._STONE_DETAIL_TYPE = self._RESULT_PAGE_TYPE == RESULT_MY_CART ? STONE_DETAIL_CART : STONE_DETAIL_RESULT;
DetailVC.delegate = self;
DetailVC.view.tag = TAG_DETAIL_CONTROLLER;
[cell.contentView addSubview:stoneDetailVC.view];
//Cell Frame
CGRect frame = cell.bounds;
frame.size.height = cellDetailHeight;
cell.frame = frame;
cell.contentView.frame = CGRectMake(0, 0, CGRectGetWidth(cell.frame), CGRectGetHeight(cell.frame));
//Stone Detail VC Frame
frame = stoneDetailVC.view.frame;
DetailVC.view.frame = CGRectMake(0, 0, CGRectGetWidth(stoneDetailVC.view.frame), cellDetailHeight);
}
I've added ViewController into cell as sub view. I want to set table cell in view full screen with bounce animation. Please help me.

Aligning text in UITableView

I have a cell. Whenever the text in cell row is equal to "(null)" I want the label to be on the right hand side of the the cell.
Here is my code at the moment, but it isn't doing anything. No errors, it just doesn't align to the right hand side of the cell. Any ideas?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"ChatListItem";
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if([[itemAtIndex objectForKey:#"user"] isEqualToString:#"(null)"]){
cell.textLabel.textAlignment=UITextAlignmentRight;
cell.detailTextLabel.textAlignment=UITextAlignmentRight;
}
cell.textLabel.text = [itemAtIndex objectForKey:#"text"];
cell.detailTextLabel.text = [itemAtIndex objectForKey:#"user"];
return cell;
}
First, did you step through the code and check the contents of the value for keys "user" and "text"?
If all is as expected, you should do the following:
Replace UITextAlignmentRight with NSTextAlignmentRight to silence compiler warnings.
Explicitly set NSTextAlignmentRight and NSTextAlignmentLeft, otherwise you will not get the correct update in recycled cells.
Finally, make sure the label's width is fixed. Otherwise, the width of the label will be based on its content, so that the alignment (within the label) loses its effect.
The only working solution for your case (without subclassing of the UITableViewCell of course)
is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ChatListItem";
NSDictionary *dict = [_tableData objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = dict[#"text"];
cell.detailTextLabel.text = dict[#"user"];
if ([dict[#"user"] isEqualToString:#"(null)"]) {
[self performSelector:#selector(alignText:) withObject:cell afterDelay:0.0];
}
return cell;
}
- (void)alignText:(UITableViewCell*)cell
{
CGRect frame = cell.textLabel.frame;
frame.origin.x = cell.frame.size.width - (frame.size.width + 10.0);
cell.textLabel.frame = frame;
frame = cell.detailTextLabel.frame;
frame.origin.x = cell.frame.size.width - (frame.size.width + 10.0);
cell.detailTextLabel.frame = frame;
[cell setNeedsDisplay];
}
As for me, I would better make a subclass.

TableView changes cell content while scrolling

I know, this is asked several times and it is answered everytime more than 1 time, but no one, of these solutions helped myself!
When my TableView opens, I can see one row of text, instead of >10! So I scroll down and 2 cells later its presented the right way! If I scroll up again, I can see the cell with this single line, is presenting everything right, too!
So, here is my question: What went wrong in my code?!
This is my cellForRowAtIndexPath:
NSString *CellIdentifier = #"Cell";
AACTickerYellowCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[AACTickerYellowCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString * text = [self getTextAtIndex:indexPath];
CGSize size = [self frameForText:text sizeWithFont:nil constrainedToSize:CGSizeMake(260.0f, CGFLOAT_MAX)];
[cell.textView setFrame:CGRectMake(10, 5, 260, size.height + 20)];
cell.textView.text = text;
return cell;
Try like that and your problem disappear:
NSString *CellIdentifier = #"Cell";
AACTickerYellowCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[AACTickerYellowCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString * text = [self getTextAtIndex:indexPath];
dispatch_async(dispatch_get_main_queue(), ^{
CGSize size = [self frameForText:text sizeWithFont:nil constrainedToSize:CGSizeMake(260.0f, CGFLOAT_MAX)];
[cell.textView setFrame:CGRectMake(10, 5, 260, size.height + 20)];
cell.textView.text = text;
});
return cell;
Maybe you missed row?
NSString * text = [self getTextAtIndex:indexPath.row]

IOS Tableview custom cell with dynamic label height

I have trying to figure out this for quite some time :
I have a custom cell in tableview which has two labels one below other. The top label can be of one line or two line max. The bottom label is restricted to just one line.
The top label will always be there but the bottom label will be there for some cells and my not be there for some other cells.
I need a way to figure out how to arrange these labels centered vertically. I tried making the top label dynamic by using cell.label1.numberOfLines = 0; But then the label1 is not really restricted to 2 lines.
I tried to center these labels vertically by computing the height of first label and then arranging both labels centered.
If I restrict the number of lines to 2 using xib, then the height for first label always computes as 2 lines, even if the label consumes 1 line. One issue always which I see is if I use [cell.label1 sizeToFit]; then while scrolling the table the label always seem to change the text shown . The text shown is always for the respective label but the text sometimes wraps midway sometimes uses the full line.
Here is my code for reference :
CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.label1.lineBreakMode = UILineBreakModeWordWrap;
cell.label1.numberOfLines = 0;
cell.label1.tag = [indexPath row];
}
cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:#"N"]) {
cell.label2.text = #"";
} else {
cell.label2.text = #"Done";
}
//[cell.label1 sizeToFit];
CGSize label1Size = [cell.label1 frame].size;
CGFloat label1Height = label1Size.height;
CGRect label1Frame = cell.label1.frame;
int numLines = (int)(label1Height/cell.label1.font.leading);
CGSize label2Size = [cell.label2 frame].size;
CGFloat label2Height = label2Size.height;
CGRect label2Frame = cell.label2.frame;
if(numLines > 1) {
if([cell.label2.text isEqualToString:#""]) {
//if label2 == "" then center label1
label1Frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = label1Frame;
} else {
label1Frame.origin.y = 12;
cell.label1.frame = label1Frame;
label2Frame.origin.y = 52;
cell.label2.frame = label2Frame;
}
} else {
if([cell.label2.text isEqualToString:#""]) {
CGRect frame = cell.label1.frame;
frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = frame;
} else {
label1Frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = label1Frame;
label2Frame.origin.y = cellHeight/2;
cell.label2.frame = label2Frame;
}
}
Please help me IOS gurus with your suggestions.
It would be better to move the resizing calculations to layoutSubviews.
//CustomCell.m
- (void)layoutSubviews{
CGRect label1Frame = self.label1.frame;
//Calculate the size of label 1
CGSize label1Size = [self.label1.text sizeWithFont:[self.label1 font]
constrainedToSize:CGSizeMake(label1Frame.size.width,42.0f)
lineBreakMode:NSLineBreakByTruncatingTail];
label1Frame.size.height = label1Size.height;
CGRect label2Frame = self.label2.frame;
//Calculate the size of label 2
CGSize label2Size = [self.label2.text sizeWithFont:[self.label2 font]
constrainedToSize:CGSizeMake(label2Frame.size.width,21.0f)
lineBreakMode:NSLineBreakByTruncatingTail];
label2Frame.size.height = label2Size.height;
//Total height of labels
CGFloat totalHeight = label1Frame.size.height+label2Frame.size.height+5.0f;
//For centering half of difference of two labels with cell
label1Frame.origin.y = (self.frame.size.height - totalHeight)/2.0f;
self.label1.frame = CGRectIntegral(label1Frame);
label2Frame.origin.y = label1Frame.origin.y+label1Frame.size.height+5.0f;
self.label2.frame = CGRectIntegral(label2Frame);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.label1.lineBreakMode = UILineBreakModeWordWrap;
cell.label1.numberOfLines = 2;
cell.label1.tag = [indexPath row];
}
cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:#"N"]) {
cell.label2.text = #"";
} else {
cell.label2.text = #"Done";
}
return cell;
}

IOS UITableView "Delete" button does not appear

I am developing app where users can create Posts with attachments. For attachments I have used UITableView and rotated it in horizontal mode in viewDidLoad method as following:
// Rotates the view.
CGAffineTransform transform = CGAffineTransformMakeRotation(-1.5707963);
imageAttachmentTableView.transform = transform;
When the user chooses images from Photo Library, they are loaded in UITableView's imageView.
- (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];
}
// Configure the cell...
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.imageView.transform = transform;
cell.imageView.frame = CGRectMake(0, 0, 110, 110);
cell.imageVenter image description hereiew.image = [imageAttachments objectAtIndex:indexPath.row];
return cell;
}
cell.imageView is again rotated in opposite direction so that image should be visible in actual orientation
UITableView is made in editing mode so that when the images are loaded, they can also be removed by single tap.
- (void)viewWillAppear:(BOOL)animated {
[imageAttachmentTableView setEditing: YES animated: YES];
}
I have also changed the default "Delete" text to "X"
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return #"X";
}
The code is working perfectly in Portrait mode as in following screen, when the user taps '-' button 'X' appears.
http://img5.imageshack.us/img5/1125/screenshot20121221at742.png
Problem is in Landscape mode, the (-) button appears but 'X' button does not appear.
http://img833.imageshack.us/img833/6305/screenshot20121221at747.png
I have tried all possible solutions, but could not make any stick, please help
Solved it!
Problem was that in landscape mode, the UITableViewCell size and Delete button frame was changed, so i subclass UITableViewCell with my custom class.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
OMAttachmentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[OMAttachmentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
CGAffineTransform transform = CGAffineTransformMakeRotation(1.5707963);
cell.imageView.transform = transform;
cell.imageView.frame = CGRectMake(0, 0, 110, 110);
cell.imageView.image = [imageAttachments objectAtIndex:indexPath.row];
return cell;
}
In my OMAttachmentCell class, i implemented the following method.
-(void) willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIView *deleteButtonView = (UIView *)[subview.subviews objectAtIndex:0];
CGRect f = deleteButtonView.frame;
f.origin.x = 0;
f.origin.y = 0;
f.size.width = 30;
f.size.height = 34;
CGRect sf = self.frame;
sf.size.width = 110;
sf.size.height = 110;
deleteButtonView.frame = f;
self.frame = sf;
}
}
}
}
Here i just updated the Delete Button frame and TableCell size.

Resources