Tableview cells only displaying correctly on scroll up - ios

I'm struggling with creating a tableview with custom, subclassed cells created in storyboards.
All the cells work well except the "questionCell". This cell only shows a fragment of its textfield (or sometimes none of it) until I scroll down and then back up again.
The initial appearance:
After scrolling down then up again:
Where am I going wrong?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier1 = #"TextCell";
static NSString *CellIdentifier2 = #"QuestionCell";
static NSString *CellIdentifier3 = #"ImageCell";
NSInteger section = indexPath.section;
NSInteger row = indexPath.row;
UITableViewCell *cell = nil;
if (section == 0){
//the intro section
TextCell *textCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
textCell.labelText.text = _intro;
cell = textCell;
} else if (section == 4){
//this is the "the answer is . . ." section
TextCell *textCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
textCell.labelText.text = [NSString stringWithFormat:#"The only EOM to not be eliminated is %#",_theAnswer];
cell = textCell;
} else {
if (row == 0) {
NSString *item = [NSString stringWithFormat:#"question_%li", (long) section];
NSString *txt = [self valueForKey: item];
QuestionCell *qCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
qCell.questionText.text = txt;
cell = qCell;
} else if (row == 1) {
NSString *item = [NSString stringWithFormat:#"img_%li", (long)section];
NSString *img = [self valueForKey: item];
ImageCell *iCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3 forIndexPath:indexPath];
iCell.image.image = [UIImage imageNamed: img];
cell = iCell;
} else {
TextCell *textCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
NSString *item = [NSString stringWithFormat:#"explain_%li", (long)section];
NSString *txt = [self valueForKey: item];
textCell.labelText.text = txt;
cell = textCell;
}
}
return cell;
}
Here's heightForRowAtIndexPath. The results are the same if I just comment this out and set the heights in the prototype cells.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
// Return NO if you do not want the specified item to be editable.
CGFloat hgt = 70;
if (indexPath.section == 0){
//the intro
hgt = 150;
} else if (indexPath.section == 4){
//the "answer is . . ."
hgt = 100;
} else {
if (indexPath.row == 1) {
//the image
hgt = 225;
} else if (indexPath.row == 2){
//the discussion
hgt = 180;
}
}
return hgt;
}
the questionCell just sets the iboutlet:
#import <UIKit/UIKit.h>
#interface QuestionCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UITextView *questionText;
#end

Related

How do I show multiple custom cells using objective C?

I have a few custom cells that I would like to display information on. I made 2 new cells however it is only returning one cell. The top most cell's identifier is "Cell" and the bottom one is "quantityCell". I would like the product description to be on the top cell and the quantity on the bottom cell. The output I am getting now is only the quantity cell showing, but not the product cell. If I remove the quantity cell, the product cell will show. How should I go about doing this?
Thank you
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *quantityCellIdentifier = #"quantityCell";
UITableViewCell *quantityCell = [tableView dequeueReusableCellWithIdentifier:quantityCellIdentifier forIndexPath:indexPath];
DisplayInventoryTableViewController *inventoryItem = [[DisplayInventoryTableViewController alloc]init];
self.productName = [inventoryItem getProductTitle];
productTitle = self.productName;
cell.detailTextLabel.text = productTitle;
NSLog(#"productTitle %#", self.productName);
cell.textLabel.text = #"Product Title";
self.productQuantity = [inventoryItem getQuantity];
quantityCell.textLabel.text = #"Quantity";
quantityCell.detailTextLabel.text = self.productQuantity;
/*
// Configure the cell...
// cell.textLabel.text = productTitle;
cell.textLabel.text = #"Product Name";
cell.detailTextLabel.text = productTitle;
*/
return cell;return quantityCell;
}
Problem
The you can't return 2 parameters in the same time on a method. So where you say:
return cell;return quantityCell;
Only cell is being returned, the method ends on the first return.
Solution
You need to make logic which one time returns topCell and the other time bottomCell
So in your case you just need to have indexPath.row modulus 2, which can take any value and returns only 0 on even numbers and 1 on odd numbers.
So your code should be like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"";
if (indexPath.row%2==0) {
//Get the top cell
CellIdentifier = #"Cell";
} else {
//Get bottom cell
CellIdentifier = #"quantityCell";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
DisplayInventoryTableViewController *inventoryItem = [[DisplayInventoryTableViewController alloc]init];
if (indexPath.row%2==0) {
//Customize topCell
self.productName = [inventoryItem getProductTitle];
productTitle = self.productName;
cell.detailTextLabel.text = productTitle;
NSLog(#"productTitle %#", self.productName);
cell.textLabel.text = #"Product Title";
} else {
//Customize bottom cell
self.productQuantity = [inventoryItem getQuantity];
cell.textLabel.text = #"Quantity";
cell.detailTextLabel.text = self.productQuantity;
}
return cell;
}
return cell;
return quantityCell;
The above 2 line you wrote in your function! After return statement the method stop executing further lines.
You could do something like this:
self.productName = [inventoryItem getProductTitle];
self.productQuantity = [inventoryItem getQuantity];
productTitle = self.productName;
if(indexPath.row == 0) {
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.detailTextLabel.text = productTitle;
cell.textLabel.text = #"Product Title";
return cell;
}
else {
NSString *quantityCellIdentifier = #"quantityCell";
UITableViewCell *quantityCell = [tableView dequeueReusableCellWithIdentifier:quantityCellIdentifier forIndexPath:indexPath];
quantityCell.textLabel.text = #"Quantity";
quantityCell.detailTextLabel.text = self.productQuantity;
return quantityCell;
}
Hope this helps.. :)
Thank you all, I ended up using a dictionary that returns all of the keys and values to the cells.
NSDictionary *inventoryDictionary = #{
#"Quantity" : productQuantity,
#"Price" : productPriceValue,
#"Product Title" : productTitle
};
NSLog(#"ProductStrings: %#", inventoryDictionary);
NSString *keys = [inventoryDictionary allKeys][indexPath.row];
NSString *providerNameString = keys;
cell.textLabel.text = providerNameString;
NSString *Values = [inventoryDictionary allValues][indexPath.row];
NSString *providerNameValue = Values;
cell.detailTextLabel.text = providerNameValue;
return cell;

How to design custom cell row wise individually in ios?

Could any one help me? Am working on expanding cell for the past one week Finally i can able to add sub menu in it. I designed two custom cells and using plist i added menu and sub menu to that. It is working well i added menu and sub menu. Now my problem is i want to add image and button to row 1,2,4,6 only using indexpath.row i assigned but this code assigning image and button to all rows But i only want to add to row 1,2,4,6 only ho i can do this pls some one help me???
interface MyHomeView ()
{
NSMutableArray *LeftPaneList;
NSArray *datalist;
}
#property (assign)BOOL isOpen;
#property (nonatomic,retain)NSIndexPath *selectIndex;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"LeftPaneMenuList" ofType:#"plist"];
LeftPaneList = [[NSMutableArray alloc] initWithContentsOfFile:path];
self.isOpen=NO;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [LeftPaneList count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.isOpen) {
if (self.selectIndex.section == section) {
return [[[LeftPaneList objectAtIndex:section] objectForKey:#"SubMenu"] count]+1;;
}
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.isOpen&&self.selectIndex.section == indexPath.section&&indexPath.row!=0) {
static NSString *CellIdentifier = #"MyHomeViewCell2";
MyHomeViewCell2 *cell = (MyHomeViewCell2*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
NSArray *list = [[LeftPaneList objectAtIndex:self.selectIndex.section] objectForKey:#"SubMenu"];
cell.name.text = [list objectAtIndex:indexPath.row-1];
return cell;
}
else
{
static NSString *CellIdentifier = #"MyHomeViewCell";
MyHomeViewCell *cell = (MyHomeViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
cell.tag=indexPath.row;
NSString *name = [[LeftPaneList objectAtIndex:indexPath.section] objectForKey:#"MenuName"];
cell.MyHomeMenuLabel.text = name;
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
if ([indexPath isEqual:self.selectIndex]) {
self.isOpen = NO;
[self didSelectCellRowFirstDo:NO nextDo:NO];
self.selectIndex = nil;
}else
{
if (!self.selectIndex) {
self.selectIndex = indexPath;
[self didSelectCellRowFirstDo:YES nextDo:NO];
}else
{
[self didSelectCellRowFirstDo:NO nextDo:YES];
}
}
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didSelectCellRowFirstDo:(BOOL)firstDoInsert nextDo:(BOOL)nextDoInsert
{
self.isOpen = firstDoInsert;
[self.MyHomeTableView beginUpdates];
int section = self.selectIndex.section;
int contentCount = [[[LeftPaneList objectAtIndex:section] objectForKey:#"SubMenu"] count];
NSMutableArray* rowToInsert = [[NSMutableArray alloc] init];
for (NSUInteger i = 1; i < contentCount + 1; i++) {
NSIndexPath* indexPathToInsert = [NSIndexPath indexPathForRow:i inSection:section];
[rowToInsert addObject:indexPathToInsert];
}
if (firstDoInsert)
{ [self.MyHomeTableView insertRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
else
{
[self.MyHomeTableView deleteRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
[self.MyHomeTableView endUpdates];
if (nextDoInsert) {
self.isOpen = YES;
self.selectIndex = [self.MyHomeTableView indexPathForSelectedRow];
[self didSelectCellRowFirstDo:YES nextDo:NO];
}
if (self.isOpen) [self.MyHomeTableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionTop animated:YES];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 52;
}
This is the original o/p!
But i want o/p like this
some one help me??
you need to specify IndexPath.section First then you can check with IndexPath.row like Bellow Example:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.section==0)
{
if(indexPath.row==0)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==2)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==4)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else if(indexPath.row==6)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
}
}
}
Th easy way to do this, is to set up 2 different dynamic prototype cells in the storyboard, each with its own identifier. In cellForRowAtIndexPath: dequeue the correct type of cell based on the indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (indexPath.row = 1 || indexPath.row = 2 || indexPath.row = 4 || indexPath.row = 6){
cell = [tableView dequeueReusableCellWithIdentifier:#"CellWithButton" forIndexPath:indexPath];
}else{
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
}
As you are using dequeueReusableCellWithIdentifier: method, it will just give cell at index path 2, 4, 6 etc to some other cell in tableView. Instead use array to store your cell and then retrieve it from array. And then you can use indexpath.row

UITableView + 2 Custom Cells = Wrong with heights

I have a UITableView which should show news.
I did set up 2 custom cells -> one has the news without an image, and the other one has the news with image.
So the cells need different heights. In storyboard I created those 2 Cells and they each have a custom height (280 with image, 130 without).
For testing purposes I want the first and the third cell to be a news cell + image.
So thats my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary * news = [postArray objectAtIndex:indexPath.row]; //PostArray is the array with the news
NSDictionary *authorData = [news valueForKey:#"author"];
NSString *postTitle = [self decodedString:[news valueForKey:#"title"]];
//Decode = change html chars
NSString *postExcerpt = [self decodedString:[news valueForKey:#"excerpt"]];
NSString *postComments = [news valueForKey:#"comment_count"];
//NSString *postID = [news valueForKey:#"id"];
NSString *authorFirstName = [self decodedString:[authorData valueForKey:#"first_name"]];
NSString *authorLastName = [self decodedString:[authorData valueForKey:#"last_name"]];
NSString *authorNickName = [self decodedString:[authorData valueForKey:#"nickname"]];
if (indexPath.row == 0 || indexPath.row == 2){
NewsCellImage *cell = (NewsCellImage *)[tableView dequeueReusableCellWithIdentifier:#"NewsCellImage"];
if (cell == nil) {
cell = [[NewsCellImage alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"NewsCellImage"];
}
// Set up the cell
cell.postTitle.text = postTitle;
cell.postExcerpt.text = postExcerpt;
cell.postCommentsCount.text = [NSString stringWithFormat:#"%i",indexPath.row];
//Check if names are empty
if ([authorFirstName length] == 0 && [authorLastName length] == 0){
cell.postMeta.text = [NSString stringWithFormat:#"%# / %#",authorNickName,[news valueForKey:#"date"]];
} else {
cell.postMeta.text = [NSString stringWithFormat:#"%# %# / %#",authorFirstName,authorLastName,[news valueForKey:#"date"]];
}
//Set Image
NSDictionary *imageData = [news valueForKey:#"thumbnail_images"];
NSDictionary *imageDataFull = [imageData valueForKey:#"large"];
NSString *postImage = [imageDataFull valueForKey:#"url"];
[cell.postImage setImageWithURL:[NSURL URLWithString:postImage]
placeholderImage:[UIImage imageNamed:#"menu"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
if (error){
NSLog(#"Error bei Bild laden: %#",postTitle);
}
} usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
return cell;
} else {
NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:#"NewsCell"];
if (cell == nil) {
cell = [[NewsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"NewsCell"];
}
// Set up the cell
cell.postTitle.text = postTitle;
cell.postExcerpt.text = postExcerpt;
cell.postCommentsCount.text = [NSString stringWithFormat:#"%#",postComments];
//Check if names are empty
if ([authorFirstName length] == 0 && [authorLastName length] == 0){
cell.postMeta.text = [NSString stringWithFormat:#"%# / %#",authorNickName,[news valueForKey:#"date"]];
} else {
cell.postMeta.text = [NSString stringWithFormat:#"%# %# / %#",authorFirstName,authorLastName,[news valueForKey:#"date"]];
}
return cell;
}
}
The code does work in general and thats what I can see after starting the app:
http://cl.ly/image/320K1y081T3Z
But when I scroll down to the next cell with Image something goes wrong:
http://cl.ly/image/2M2O1X3R2T13
So something is wrong with my code or I need to add something - but I dont know which way to take.
Maybe it's something with
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexpath{ }
But I really dont know. I appreciate help. Ty
Try this method.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexpath{
if (indexPath.row == 0 || indexPath.row == 2){
return newsWithImageHeight;
}
else return newsHeight;
}
Or you can check autolayout setting for cell in interfacebuilder
How does your:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexpath{ }
look then?
I think you need something like:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexpath{
if (indexpath.row == 0 || indexpath.row == 2) {
return 280;
}
return 130;
}

how to change the UITableViewCell

I have 2 tableViewCell in tabbar. copy values ​​from one button to another, and if the values ​​match the counter is incremented, and the Cell is removed. In managedCoreData
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * result = nil;
static NSString * OrederTableViewCell = #"OrderTableViewCell";
result = [tableView dequeueReusableCellWithIdentifier:OrederTableViewCell];
if (result == nil)
{
result = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:OrederTableViewCell];
result.selectionStyle = UITableViewCellSelectionStyleNone;
}
Order * order = [self.orderFRC objectAtIndexPath:indexPath];
result.textLabel.text = order.name;
result.imageView.image = [UIImage imageWithData:[order imageSmall]];
self.count = 1;
if ([order.name characterAtIndex:indexPath.row] == [order.name characterAtIndex:indexPath.row+1])
{
self.count++;
[[self managedObjectContext]deleteObject:order];
}
result.detailTextLabel.text = [NSString stringWithFormat:#"X = %d",self.count];
return result;
}

How can I solve this delegate error?

I have a delegate, but it doesn't work without the other delegate line in it:
- (id)initWithData:(NSData *)data delegate:(id <ParseOperationDelegate>)theDelegate {
self = [super init];
if (self != nil) {
self.dataToParse = data;
self.delegate = theDelegate;
}
appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
It should load data in a Cell but the data isn't shown before the first scroll. What can I do?
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"productCell";
static NSString *PlaceholderCellIdentifier = #"placeholderCell";
int nodeCount = [appDelegate.products count];
if (nodeCount == 0 && indexPath.row == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.detailTextLabel.text = #"Loading...";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (nodeCount > 0) {
XMLProductView *listedProduct = [appDelegate.products objectAtIndex:indexPath.row];
cell.textLabel.text = listedProduct.name;
// cell.detailTextLabel.text = appRecord.artist;
if (!listedProduct.productImage) {
if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
[self startImageDownload:listedProduct forIndexPath:indexPath];
}
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = [UIImage imageNamed:#"Placeholder.png"];
}
else {
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = listedProduct.productImage;
}
}
return cell;
}
your code seems that its waiting for some event, or some files to get fetched or downloaded, so you will need to call [tableview reloadData]; when this data is downloaded,
I cant figure it out from the code, but my guts tells me this
1st:
that you are waiting for data from int nodeCount = [appDelegate.products count]; to be ready, so you will need to have some sort of delegate that gets called when this data is ready
2nd:
you are waiting for an image to get downloaded here [self startImageDownload:listedProduct forIndexPath:indexPath], so when this actually get downloaded you will need to set the image to that cell or reloadData on the table
That is what i can figure out from the code.

Resources