I've noticed the cells are taken out of memory when scrolled out of view and then added back into memory when scrolled into view.
I get the performance reasons for this, but since my table only has a couple of cells out of view, is there a way to turn off this caching feature?
You could try using a different cell identifier for each index path.
That way, the UITableView won't be able to find a cell to dequeue, and a new one will be provided.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString * CellIdentifier = [NSString stringWithFormat:#"%d - %d", indexPath.row, indexPath.section];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
return cell;
}
You could also skip queuing/dequeing entirely, and retain a reference to them yourself, then just return them in the cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [myCells objectAtIndex:indexPath.row];
}
Where myCells is an array holding your UITableViewCells.
Related
I am following this tutorial: http://www.appcoda.com/ios-programming-tutorial-create-a-simple-table-view-app/ which shows how to create an UITableView and populate it programmatically. All's good, it works.
Now, I am trying to make the table fill the screen: regardless of the device or orientation. I did this:
But now the table view simply does not appear in my screen (I imagine it is somewhere far away due to a problem with the constraints?).
There really isn't much code for me to show. I literally just placed an UITableView into the interface builder, and followed that tutorial to set the delegate to my view controller. The methods would be
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
Where tableData is an array with 16 strings.
Try to remove all constraints, then select your tableView and add their again and press Add 4 constraints. Be sure, you don't have some ambiguity.
I have the following code to create my cells in a UITableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"futureAppointments";
FutureAppointmentsViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
[tableView registerNib:[UINib nibWithNibName:#"FutureAppointmentsViewCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
cell = [[FutureAppointmentsViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
NSUInteger position = indexPath.row;
cell.appointmentDescription.text = [NSString stringWithFormat:#"%lu. %#. %#", (unsigned long)position, #"Steve", #"10/03/"];
return cell;
}
The problems is, the first cell of the tableView is missing. It should start with 0. Steve but instead starts with 1. Steve. Also there are only 4 elements in the list instead of 5.
When I place a break point in the code, the first cell is nil.
Does anyone know what might be happening?
Put this line of code:
[tableView registerNib:[UINib nibWithNibName:#"FutureAppointmentsViewCell"
bundle:nil]
forCellReuseIdentifier:CellIdentifier];
In viewDidLoad. It doesn't belong in cellForRowAtIndexPath. Once you do this then you no longer need to check whether the cell is nil.
Change cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"futureAppointments";
FutureAppointmentsViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSUInteger position = indexPath.row;
cell.appointmentDescription.text =
[NSString stringWithFormat:#"%lu. %#. %#",
(unsigned long)position, #"Steve", #"10/03/"];
return cell;
}
I think I had similar problem when I was using UITableView inside UIView and initialized it in init method.
I was not able to find good explanation for that behavior, but I've found tricky solution for that - I was reloading UITableView instance from UIViewController in viewDidAppear method.
I would also like to know, why UITableView is not drawing all UITableViewCell.
I'm developing an iOS 7+ app, and I've some UITableViewController in storyboard that are showing a weird behavior. I've a basic prototype cell defined in one of them, with an identifier #"standardCell" also set in storyboard. In the associated UITableViewController class, I've this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
Cells are loaded the first tiem the table view is shown, but as soon as I scroll the table content, all cell titles that were set appear empty and cellForRowAtIndexPath: is not called anymore. The didSelectRowAtIndexPath: delegate method is neither called.
I've set both delegate and dataSource for this table view to be the table view controller. And its .h file conforms to UITableViewController <UITableViewDataSource, UITableViewDelegate>.
I find a similar issue with another table view and associated view controller, where prototype cell is a custom cell instead: cells show wrong data and weird content when I scroll the table, as if cells where not being dequeued and reused as expected.
What could I being missing?
Thanks
at least in this method:
Change this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
To this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"standardCell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
I feed a UITableView with a list of names and images from a JSON. "SDWebImage" handles images download. It works OK apart from the fact that the images move to the left when the user selects a row or when scrolls the table view.
Two screen captures to show the issue.
Interface Builder setup
Implementation is pretty standard:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil ) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [[array objectAtIndex:indexPath.row]objectForKey:#"marca"];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
[cell.imageView setImageWithURL:[NSURL URLWithString:[[array objectAtIndex:indexPath.row]objectForKey:#"photoUrl"]]placeholderImage:[UIImage imageNamed:#"placeholder.png"] ];
return cell;
}
What can I do to stop images moving?
I've just had a similar issue on an app and found it was because I was re-using UITableViewCells default imageView IBOutlet.
After creating my a new IBOutlet, called something other than imageView, and hooking it up it resolved the issue.
I don't know what I am doing wrong but the cellForRowAtIndexPath method of table view is getting called only once.
Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"--->%d",[collaboratoresdata count]);
return [collaboratoresdata count];
}
When my collaboratoresdata array is filled, then I am calling [_collaboratortblView reloadData] to reload the table view.
I am successfully getting 3 in NSLog(#"--->%d",[collaboratoresdata count]); but cellForRowAtIndexPath is getting called only one time.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// add a placeholder cell while waiting on table data
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
NSLog(#"tableView:%d",[indexPath row]);// i am getting 0 here than after its not calling
return cell;
}
check the height of cell i think thats the issue
please try to set height of cell manually(custom). So, if problem of cell height then it will be resolved. below method set cell height 30 pixels.
#pragma mark- TableView delegate Methods
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 30.0f;
}