I'm using one type of Custom Table View Cell, but when other data is posted to my Table View, I want it to be displayed in a different Custom Table View Cell in the same table.
For example, I've created a chat in my Table View. However when certain details are posted, I want a separate cell design to display these details. See my code below so far.
My question: How can I write, "If field_swaptime in self.messages is empty, display ChatTableViewCell - if it contains data, display SwapDetailTableViewCell" ?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ChatTableIdentifier = #"ChatTableViewCell";
static NSString *ChatTableIdentifier2 = #"SwapDetailTableViewCell";
NSDictionary *data = [self.messages objectAtIndex:indexPath.row];
if ( [data objectForKey:#"field_swaptime"] == nil ) {
NSLog(#"THIS IS DATA %#", data);
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *userName = [data objectForKey:#"name"];
[cell.sendingUser setText:userName];
NSString *messageBody = [data objectForKey:#"body"];
[cell.messageDisplayed setText:messageBody];
NSString *timeReceived = [data objectForKey:#"published at"];
NSLog(#"Message Received at %#", timeReceived);
[cell.timeStamp setText:timeReceived];
return cell;
}
else {
SwapDetailTableViewCell *cell = (SwapDetailTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier2];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SwapDetailTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *Time = [data objectForKey:#"field_swaptime"];
NSLog(#"This is time %#", Time);
[cell.startTime setText:Time];
NSString *TimeEnd = [data objectForKey:#"field_endswaptime"];
[cell.endTime setText:TimeEnd];
return cell;
}
}
You are basically looking to write your initial if as:
NSDictionary *data = [self.messages objectAtIndex:indexPath.row];
//
// if self.messages is nil, then data will be nil and we'll display
// a ChatTableViewCell as before. If data is valid, but there is no
// value associated with "field_swaptime", then again, we'll display
// a ChatTableViewCell. However, if self.messages IS valid and
// there IS a value associated with "field_swaptime" key, then the
// if clause fails, and we execute the else and return a
// SwapDetailTableViewCell.
//
if ( !data || ![data objectForKey:#"field_swaptime"] } {
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *userName = [data objectForKey:#"name"];
[cell.sendingUser setText:userName];
NSString *messageBody = [data objectForKey:#"body"];
[cell.messageDisplayed setText:messageBody];
NSString *timeReceived = [data objectForKey:#"published at"];
NSLog(#"Message Received at %#", timeReceived);
[cell.timeStamp setText:timeReceived];
return cell;
}
else {
SwapDetailTableViewCell *cell = (SwapDetailTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier2];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SwapDetailTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *Time = [data objectForKey:#"field_swaptime"];
[cell.startTime setText:Time];
NSString *TimeEnd = [data objectForKey:#"field_endswaptime"];
[cell.endTime setText:TimeEnd];
return cell;
}
Bonus: if self.messages is valid, and data is valid, then you already have data and don't need to multiple calls to [self.messages objectAtIndex:indexPath.row]. (you should do a bounds sanity check on self.messages.count against indexPath.row before calling objectAtIndex:indexPath.row, but the defensive coding part is up to you to put together)
Objective C is pretty nifty in that calling a method on nil object, just returns nil. So, it is perfectly valid to ignore whether self.messages is valid or not, and just retrieve the data it contains. If it is valid (and your index is in bounds of the array), then a valid NSDictionary will be returned that you can use throughout the if/else clause.
The type of cell you get is determined by the type you register to correspond with the identifier. So, when you're setting up the table (say, in viewDidLoad)...
UINib *nib = [UINib nibWithNibName:#"ChatTableViewCell" bundle:nil]; // bundle:nil means main bundle
[self.tableView registerNib:nib forCellReuseIdentifier:#"ChatTableIdentifier"];
UINib *nib2 = [UINib nibWithNibName:#"OtherTableViewCell" bundle:nil];
[self.tableView registerNib:nib2 forCellReuseIdentifier:#"OtherIdentifier"];
Then, in cellForRowAtIndexPath, you use the modern dequeue method, dequeueReusableCellWithIdentifier:forIndexPath:, which never returns nil and always returns an instance built from the nib you registered earlier...
// generically
NSString *identifier = (/*some condition*/)? #"ChatTableIdentifier" : #"OtherIdentifier";
// or alternatively, given the condition in your comment...
NSString *identifier = (!data[#"field_swaptime"])? #"ChatTableIdentifier" : #"OtherIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
// now cell is one of your two custom classes, built from their respective nibs.
Based on the same condition, you can cast cell to either kind, and configure it...
if (/*same condition as identifier*/) {
ChatTableViewCell *chatCell = (ChatTableViewCell *)cell;
// do your config for this type here
} else {
OtherTableViewCell *otherTypeCell = (OtherTableViewCell *)cell;
// do your config for this other type here
}
return cell;
Related
I am using the following code to have a tab view. When you click one tab it expands downwards, this is currently working okay but if I open the first tab with the indexPath of 0 which should load a separate custom opened view it will load but then when I go to the other indexPath tabs it displays the same view but if I reload the app and go to the other tabs first they load the correct view. It's nearly like the app is making a cache?
Is there any way to solve this??
Thanks
- (void)viewDidLoad {
row = 1000;
NSLog(#"row is %d", row);
[super viewDidLoad];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
infoStory = [userDefaults objectForKey:#"storyname"];
// Do any additional setup after loading the view.
numbers = [NSArray arrayWithObjects:#"1", #"2", #"3", #"4", #"5", #"6", #"7", #"8", nil];
// Initialize thumbnails
text = [NSArray arrayWithObjects: #"Arriving by Bus or Train", #"Arriving by Car (Autobahn 5)", #"Arriving by Car (Autobahn 6)", #"Wifi", #"Registration", #"Refreshments", #"Evening Event", #"Contact Information", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(row == indexPath.row){
if(indexPath.row == 0){
static NSString *simpleTableIdentifier2 = #"TableViewCellOPENEDbustaxi2";
TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableViewCellOPENEDbustaxi2" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.text.text = [text objectAtIndex:indexPath.row];
return cell;
}
else{
static NSString *simpleTableIdentifier = #"TableViewCellOPENED";
TableViewCell1 *cell2 = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell2 == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableViewCellOPENED" owner:self options:nil];
cell2 = [nib objectAtIndex:0];
}
cell2.text.text = [text objectAtIndex:indexPath.row];
return cell2;
}
}
else{
static NSString *simpleTableIdentifier = #"TableViewCellINFO";
TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableViewCellINFO" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.text.text = [text objectAtIndex:indexPath.row];
return cell;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [numbers count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(row == indexPath.row){
row = 1000;
NSLog(#"row is %d", row);
[self.tableViewObject reloadData];
}
else{
row = indexPath.row;
NSLog(#"row is %d", row);
[self.tableViewObject reloadData];
}
}
#end
I think the problem might be that you did not specify the correct reuse identifier in the attributes inspector of the cell in your XIB file(s). You should check if you use the wrong one somewhere, so dequeueing will return an unexpected cell.
You could also set the appropriate reuseIdentifier manually, with a little setValue:forKey: trick:
static NSString *simpleTableIdentifier2 = #"TableViewCellOPENEDbustaxi2";
TableViewCell1 *cell = (TableViewCell1 *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableViewCellOPENEDbustaxi2" owner:self options:nil];
cell = [nib objectAtIndex:0];
[cell setValue:simpleTableIdentifier2 forKey:#"reuseIdentifier"];
}
and so on for the other cells and identifiers.
I have 3 custom table cells in my UITableView. The first two cells have set positions followed by a random number of cells.
For my row count I use :
return [stepLabel count] +2;
And for my tablecells I use :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *stepsCellIdentifier = #"StepsViewCell";
static NSString *descIdentfier = #"descViewCell";
static NSString *videoCellIdentfier = #"videoViewCell";
if( indexPath.row == 0 ) {
UITableViewCell *cell = nil;
cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:videoCellIdentfier];
if( !cell ) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"videoViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.textLabel.text = [descLabel objectAtIndex:indexPath.row];
return cell;
}
else if( indexPath.row == 1 ) {
stepDescCell *cell = nil;
cell = (stepDescCell *)[tableView dequeueReusableCellWithIdentifier:descIdentfier];
if( !cell ) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"descViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.descTextLabel.text = [descLabel objectAtIndex:indexPath.row - 1];
return cell;
}
else {
StepViewCell *cell = nil;
cell = (StepViewCell *)[tableView dequeueReusableCellWithIdentifier:stepsCellIdentifier];
if( !cell ) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StepsViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.stepTextLbl.text = [stepLabel objectAtIndex:(indexPath.row - 2)];
NSString *imageThumb = [thumbImg objectAtIndex:(indexPath.row - 2)];
[cell.thumbImage setImage:[UIImage imageNamed: imageThumb] forState:UIControlStateNormal];
return cell;
}
}
All this works perfectly, however when I try to send a string from the table across a segue to another UIViewController I get the following error:
index (-2 (or possibly larger)) beyond bounds (3)'
The prepare for segue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"imageBigShow"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
imageBigViewController *destViewController = segue.destinationViewController;
NSString *largeImgString = [largeImg objectAtIndex:(indexPath.row - 2)];
destViewController.imageBigString = largeImgString;
}
}
What am I doing wrong?
UPDATE
#implementation detailViewController
{
NSArray *thumbImg;
NSArray *stepLabel;
NSArray *descLabel;
NSArray *largeImg;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Find out the path of recipes.plist
NSDictionary *mapping = #{
#"How to wear a Kilt" : #"wearAKilt",
#"How to tie a cravat" : #"wearACravat",
#"How to wear a sporran" : #"wearASporran",
#"How to tie Ghillie Brogues" : #"wearTheShoes",
#"How to wear the accessories" : #"wearAccessories",
#"How to tie a cravat" : #"wearACravat",
#"How to Measure the Neck" : #"htmNeck",
#"How to Measure the chest" : #"htmChest",
#"How to Measure the waist" : #"htmWaist",
};
NSString *name = [mapping objectForKey:self.title];
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
thumbImg = [dict objectForKey:#"thumbImg"];
stepLabel = [dict objectForKey:#"stepLabel"];
descLabel = [dict objectForKey:#"descLabel"];
largeImg = [dict objectForKey:#"largeImg"];
}
You have the following line:
NSString *largeImgString = [largeImg objectAtIndex:(indexPath.row - 2)];
If the user taps on the 1st or 2nd rows (index paths with row 0 or 1), this code will fail.
1. in my method in write code example given below -
(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
static NSString *simpleTableIdentifier2 = #"SimpleTableCell2";
if (indexPath.row== 0) {
SimpleTableCell *cell = nil;
cell=(SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
}
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (indexPath.row == 1) {
SimpleTableCell2 *cell2 = nil;
cell2=(SimpleTableCell2 *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
}
if (cell2 == nil)
{
NSArray *nib2 = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell2" owner:self options:nil];
cell2 = [nib2 objectAtIndex:0];
}
cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.prepTimeLabel.text = #"detail";// [prepTime objectAtIndex:indexPath.row];
//cell.imageView.image = [UIImage imageNamed:#"creme_brelee.jpg"];
cell2.nameLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
can any one help me am i write correct code becoz it will give an error
the error is use of undeclear identifier cell and cell2
i dont understand what is this error
it gives the error after making cell2 before cell2 it works perfectly
help me
thanks
It is giving the error because you have declared it like this:
if (indexPath.row== 0) {
SimpleTableCell *cell = nil;
cell=(SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
}
and you are using the cell variable outside the local scope of this condition.
Do this:
SimpleTableCell *cell = nil;
if (indexPath.row== 0)
{
cell=(SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
}
Also make sure that you have imported the header SimpleTableCell.h.
Hope that helps!
if (indexPath.row == 1) {
SimpleTableCell2 *cell2 = nil;
cell2=(SimpleTableCell2 *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
//This is ok
cell2.nameLabel.text = [tableData objectAtIndex:indexPath.row];
}
//No you cant access outside
cell2.nameLabel.text = [tableData objectAtIndex:indexPath.row];
Here, you have declared cell2 inside the if block. So you can use this variable in this scope only. When you try to access cell2 outside, you will get use of undeclared error.
Undeclared identifier means that you didn't register cell class.
You should do that in viewDidLoad:
-(void)viewDidLoad
{
[self.tableView registerClass:[SimpleTableCell class] forCellReuseIdentifier:#"SimpleTableCell"];
[self.tableView registerClass:[SimpleTableCell2 class] forCellReuseIdentifier:#"SimpleTableCell2"];
}
However, NSStringFromClass approach is better when dealing with cell identifiers:
-(void)viewDidLoad
{
[self.tableView registerClass:NSStringFromClass([SimpleTableCell class]) forCellReuseIdentifier:#"SimpleTableCell"];
[self.tableView registerClass:NSStringFromClass([SimpleTableCell2 class]) forCellReuseIdentifier:#"SimpleTableCell2"];
}
If you didn't register a cell class, dequeueReusableCellWithIdentifier can return nil, as specified in the docs:
This method dequeues an existing cell if one is available or creates a new one
using the class or nib file you previously registered. If no cell is available
for reuse and you did not register a class or nib file, this method returns nil.
Additional note: keep your view controller methods as slim as possibile.
you could try these codes:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
static NSString *simpleTableIdentifier2 = #"SimpleTableCell2";
if (indexPath.row== 0) {
SimpleTableCell *cell = nil;
cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.prepTimeLabel.text = #"detail";// [prepTime objectAtIndex:indexPath.row];
//cell.imageView.image = [UIImage imageNamed:#"creme_brelee.jpg"];
return cell;
}
SimpleTableCell2 *cell2 = nil;
if (indexPath.row == 1) {
cell2 = (SimpleTableCell2 *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
if (cell2 == nil){
NSArray *nib2 = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell2" owner:self options:nil];
cell2 = [nib2 objectAtIndex:0];
}
cell2.nameLabel.text = [tableData objectAtIndex:indexPath.row];
}
return cell2;
}
if (indexPath.row== 0) {
SimpleTableCell *cell = nil;
cell=(SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
return cell;
}
if (indexPath.row == 1) {
SimpleTableCell2 *cell2 = nil;
cell2=(SimpleTableCell2 *) [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
if (cell2 == nil)
{
NSArray *nib2 = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell2" owner:self options:nil];
cell2 = [nib2 objectAtIndex:0];
}
return cell2;
}
UITableViewCell *commonCell = [tableView dequeueReusableCellWithIdentifier:#"commonToALL"];
if (commonCell == nil) {
commonCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"commonToALL"];
}
return commonCell;
Try This. This will create two specific cell for index 0 and 1 while two general Cells for remainder as you have 4 rows.
You'd better check you custom cell's tag in SimpleTableCell.xib
whether the tag is 0
and just one custom cell could work like:
(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.nameLabel.text = [tableData objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.prepTimeLabel.text = #"detail";// [prepTime objectAtIndex:indexPath.row];
//cell.imageView.image = [UIImage imageNamed:#"creme_brelee.jpg"];
if (indexPath.row == 1) {
[cell.thumbnailImageView.image setHidden:Yes];
[cell.prepTimeLabel.text setHidden:Yes];
}
return cell;
}
I have a UITableView that holds an FBProfilePictureView and a UILable,
my problem is when a user scrolls the picture rebuilds its self and it takes time to show the image it self, i want to know how can i create the FBProfilePictureView once and then when the user scrolls it won't build it self again.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
Messages *msg = [messages objectAtIndex:indexPath.row];
NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
NSData *encodedDataObject = [def objectForKey:#"myUser"];
User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData: encodedDataObject];
if(![msg.wrote_id isEqualToString:user.fid])
{
NSString *idToImage = [self getOtherUserId];
NSString *CellIdentifier = #"Cell";
ChatWindowCell *cell = nil;
cell = (ChatWindowCell *)[tableChat dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ChatWindowCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[ChatWindowCell class]])
{
cell = (ChatWindowCell *) currentObject;
cell.profile_image.profileID=nil;
if(cell.profile_image.profileID.length>0)
{
return cell;
}
break;
}
}
cell.profile_image.profileID = idToImage;
NSString *text = msg.msg;
cell.lblMessage.text=text;
return cell;
}
else
{
NSString *CellIdentifier = #"Cell";
ChatCellMe *cell = nil;
cell = (ChatCellMe *)[tableChat dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ChatCellMe" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[ChatCellMe class]])
{
cell = (ChatCellMe *) currentObject;
NSLog(cell.prof_img.profileID);
cell.prof_img.profileID=nil;
if(cell.prof_img.profileID.length>0)
{
return cell;
}
break;
}
}
cell.prof_img.profileID = user.fid;
NSString *text = msg.msg;
cell.lblText.text=text;
isMessageFromMe=false;
return cell;
}
}
any help would be great guys...
thanks a lot.
I created an alternate view to solve this problem, see https://github.com/combinatorial/DBFBProfilePictureView
I'm trying to insert data into the rows I've created, I will get all info in my Log but it only shows the last info in all of my rows. Could anyone suggest a way to avoid this error?
Please offer me some advice thanks!
You are never re-populating the cells, actually. You are creating the initial visible cells, and just reusing them with the same content.. please look below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// HERE YOU ONLY WANT TO INSTANTIATE THE CELL
NSArray *topObjects = [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil];
for (id currentObject in topObjects)
{
if([currentObject isKindOfClass:[TestCell class]])
{
cell = (TestCell *) currentObject;
break;
}
}
}
// HERE YOU WOULD ACTUALLY POPULATE THE CELL WITH DATA
NSArray *array = [server get_texts:10 offset:0 sort_by:0 search_for:#""];
NSMutableString *s = [[NSMutableString alloc] init];
for (testMetaData *m in array){
[s appendFormat:#"%# %# \n", m.title,m.note];
cell.title.text = m.title;
NSLog(#" title %# ", m.title);
}
return cell;
}
Some info about UITableView:
So, a properly setup tableView only allocates and uses a limited number of UITableViewCells. After allocating, say 5 cells (this number is determined by "How many cells can you see at any given time?"), it will take an already created cell that has been scrolled out of the visible area, and gives it back to you in that method you are using, so you can re-populate it. So, cell variable will not be nil at that time, and your server code never gets called.
I think it has to do with your for loop.
NSMutableString *s = [[NSMutableString alloc] init];
for (testMetaData *m in array){
[s appendFormat:#"%# %# \n", m.title,m.note];
cell.title.text = m.title;
NSLog(#" title %# ", m.title);
}
Your cell.title.text = m.titlewill get the last m.title info at the end of the for loop.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
//Load Cell for reuse
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[ [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil] lastObject];
}
//appending text and config cell
NSArray *array = [server get_texts:10 offset:0 sort_by:0 search_for:#""];
NSString *t = [array objectAtIndex:indexPath.row];
//Config cell - Not sure what you want. Maybe 10 different rows
cell.title.text = t;
return cell;
}