riya ahuja riya ahuja - 1 year ago 101
Objective-C Question

UItableview previous cell disappears when new cell is added

I am new in IOS development.I am trying to add rows dynamically in UITableView.I am adding new row in NSMutableArray and using the same Array as table data source.But somehow when I add new cell in array by button click event and try to refresh the table,previous cell disappears.Here are sequence of actions performed on table:

step 1

enter image description here

enter image description here

enter image description here

I am stuck from last few days but I was unable to provide the solution.


#import <UIKit/UIKit.h>
#import "AppDelegate.h"

@interface SecondViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
AppDelegate *AppDel;
CGFloat viewHeight;

@property (weak, nonatomic) IBOutlet UITextField *typeTextField;
@property (strong, nonatomic) IBOutlet UIView *mainView;

@property (weak, nonatomic) IBOutlet UIVisualEffectView *blurback;
@property (weak, nonatomic) IBOutlet UITableView *tableViewAdd;
@property (weak, nonatomic) IBOutlet UIView *addView;
@property (nonatomic, retain) NSArray *myCell;
@property (weak, nonatomic) IBOutlet UIButton *addTextbutton;
- (IBAction)addButtonClick:(id)sender;



#import "SecondViewController.h"
#import "AFNetworking.h"

@interface SecondViewController () <UITableViewDelegate, UITableViewDataSource>


@implementation SecondViewController

- (void)viewDidLoad {
[super viewDidLoad];

AppDel = [[UIApplication sharedApplication] delegate];
NSMutableArray *arr = [[NSMutableArray alloc] init];
self.myCell = arr;
// Do any additional setup after loading the view, typically from a nib.
/* if (!UIAccessibilityIsReduceTransparencyEnabled()) {
self.view.backgroundColor = [UIColor clearColor];

UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
blurEffectView.frame = self.view.bounds;
blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

[self.view addSubview:blurEffectView];
} else {
self.view.backgroundColor = [UIColor blackColor];

self.blurback.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]

[self.blurback addGestureRecognizer:tap];

// [self addadd];

//self.tableViewAdd.frame=CGRectMake(0, 0,self.view.frame.size.width ,

- (void)keyboardWillShow:(NSNotification *)notification
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
viewHeight= self.addView.frame.size.height;
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.addView.frame;
f.size.height = viewHeight-keyboardSize.height;
self.addView.frame = f;
-(void)keyboardWillHide:(NSNotification *)notification
[self.view endEditing:YES];
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.addView.frame;
f.size.height = viewHeight;
self.addView.frame = f;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// return 10;
return [self.myCell count];
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

//return cell;

return self.myCell[indexPath.row];

- (NSInteger)getKeyBoardHeight:(NSNotification *)notification
NSDictionary* keyboardInfo = [notification userInfo];
NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];
NSInteger keyboardHeight = keyboardFrameBeginRect.size.height;
return keyboardHeight;
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (IBAction)addButtonClick:(id)sender
UITableViewCell *cell = [self.tableViewAdd dequeueReusableCellWithIdentifier:@"AddCell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AddCell"];
// More initializations if needed.
NSString *messageText =self.typeTextField.text;
CGSize boundingSize = CGSizeMake(260-20, 10000000);
CGSize itemTextSize = [messageText sizeWithFont:[UIFont systemFontOfSize:14]
float textHeight = itemTextSize.height+7;
int x=0;
if (textHeight>200)
if (textHeight>150)
else if (textHeight>80)
if (textHeight>50)
if (textHeight>30) {
//[bubbleImage setFrame:CGRectMake(265-itemTextSize.width,5,itemTextSize.width+14,textHeight+4)];
UIImageView *bubbleImage=[[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"light-grey-bbl"] stretchableImageWithLeftCapWidth:21 topCapHeight:14]];
[cell.contentView addSubview:bubbleImage];
[bubbleImage setFrame:CGRectMake(50,5, itemTextSize.width+18, textHeight+4)];
// bubbleImage.tag=56;
//CGRectMake(260 - itemTextSize.width+5,2,itemTextSize.width+10, textHeight-2)];
UITextView *messageTextview=[[UITextView alloc]initWithFrame:CGRectMake(60,2,itemTextSize.width+10, textHeight-2)];
[cell.contentView addSubview:messageTextview];

messageTextview.text = messageText;
messageTextview.backgroundColor=[UIColor clearColor];
messageTextview.font=[UIFont fontWithName:@"Helvetica Neue" size:12.0];
messageTextview.textColor=[UIColor blackColor];
self.myCell= [self.myCell arrayByAddingObject:cell];
[self.tableViewAdd reloadData];


Answer Source

What you are trying to do is totally wrong. In your approach you are making a UITableViewCell and then storing it in your data source. You are unnecessarily keeping the UITableViewCell's in memory when it's really the job of iOS to do it for you.

You need to make the following changes:

  1. Make a data source which is your actual data source, for example something like an array of numbers.
  2. Then in the cellForRowAtIndex use that array to display the data in the cell. Important point here is to make sure you create your cell inside this method.

Now since your table view is setup and you want to add more rows, let move forward with that. Suppose on the click of the button you want to add one or more rows, you'll do it as follows:

  1. You'll update your data source by adding more objects to it, like in step 1 we created an array of numbers, Here add some more numbers in the array.
  2. The next step would be to create index paths where you want to insert that data. In our case it'll be the bottom of the table. So you should create indexPaths for the numbers you added in the array in the previous step.
  3. Finally now your data source and array of index paths are on the same page, begin table view updates and insert the rows. That's it. :)

Created a dummy project to answer. When you run the project and scroll, you'll see that the rows are added dynamically, but the project is in swift, you'll able to figure out whats happening. https://github.com/harsh62/stackoverflow_insert_dynamic_rows