I am using hpple to get data from web page and display it in table view, but i want to cells to display " no data" if there either is no data or it can't get the data. But because of this it flases the no data on the view controller for about a second when the data is loaded here is the code i am using:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0:
if ((_deli.count > 0)) {
return _deli.count;
}
else {
return 1;
}
break;
case 1:
if ((_entrees.count > 0)) {
return _entrees.count;
}
else {
return 1;
}
break;
}
return 0
}
and then
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
//[UIColor colorWithRed:191.0f/255.0f green:48/255.0f blue:48/255.0f alpha:1.0]
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:17.0f];
if (indexPath.section == 0) {
if ([tableView numberOfRowsInSection:0] == _deli.count ) {
Items *thisDeli = [_deli objectAtIndex:indexPath.row];
cell.textLabel.text = thisDeli.title;
}
else { cell.textLabel.text = #"No Data Avaiable";
}
}
else if (indexPath.section == 1) {
if ([tableView numberOfRowsInSection:1] == _entrees.count) {
Items *thisEntree = [_entrees objectAtIndex:indexPath.row];
cell.textLabel.text = thisEntree.title;
}
else { cell.textLabel.text = #"No Data Avaiable";
}
}
}
Is there a way to delay the appearance of the "no data" phrase or only display it if it is blank or can't get it.
Heres my NSURLConnection
- (void) loadDataUsingNSURLConnection {
NSString *url = #"http://ueat.site88.net/westTest.xml";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"response == %#", response);
}
Thanks for your help in advance.
Cheers
Consider making the "No Data Available" string dynamic based on whether your call has completed to load the data or not. If the call has not completed have it use "Loading" or something like that. If the call has completed have it show the existing "No Data Available" string.
EDIT WITH EXAMPLE:
The easiest thing to do, with the code you have, is to set your _deli and _entrees variables to nil until you've loaded them, and check for that condition when displaying your message:
#interface YourViewController ()
{
NSArray *_deli;
NSArray *_entrees;
}
#end
Set the arrays to nil in your viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
_deli = nil;
_entrees = nil;
}
Change the logic in your previous code to this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0:
if (_deli == nil || _deli.count == 0) {
return 1;
}
else {
return _deli.count;
}
break;
case 1:
if (_entrees == nil || _entrees.count == 0) {
return 1;
}
else {
return _entrees.count;
}
break;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
//[UIColor colorWithRed:191.0f/255.0f green:48/255.0f blue:48/255.0f alpha:1.0]
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont fontWithName:#"TimesNewRomanPS-BoldMT" size:17.0f];
if (indexPath.section == 0) {
if (_deli == nil)
cell.textLabel.text = #"Loading";
else if (_deli.count > 0) {
Items *thisDeli = [_deli objectAtIndex:indexPath.row];
cell.textLabel.text = thisDeli.title;
}
else
cell.textLabel.text = #"No Data Avaiable";
}
else if (indexPath.section == 1) {
if (_entrees == nil)
cell.textLabel.text = #"Loading";
else if (_entrees.count > 0) {
Items *thisEntree = [_entrees objectAtIndex:indexPath.row];
cell.textLabel.text = thisEntree.title;
}
else
cell.textLabel.text = #"No Data Avaiable";
}
}
Since your loadDataUsingNSURLConnection just writes out the response I'm not sure how you're loading the array, but you should get the idea at this point. All you need to do is just load the response into the array and call the reloadData method on your table to get the new data to appear.
Related
I am working on a chat app,In that i have used UITableView for chatting screen. In every chat bubble user's profile pic is there,Now my issue is when a new message come or i am sending new message whole tableView is reloading with images in chat bubble also, I want to stop it,Can anybody help me to figure it out?
my code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.chatTableView)
{
NSString *cellID;
if([[((UUMessageFrame *)(self.chatModel.dataSource[indexPath.row])) message] from] == UUMessageFromMe)
{
cellID = #"outgoing_cell";
}
else
{
cellID = #"incoming_cell";
}
//commented by jigar
// UUMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// UUMessageCell *cell = [tableView];
UUMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UUMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
cell.delegate = self;
if ([cellID isEqualToString:#"outgoing_cell"])
{
// cell.recognizer.numberOfTapsRequired
[cell.recognizer addTarget:self action:#selector(longPress:)];
}
}
[cell setMessageFrame:self.chatModel.dataSource[indexPath.row]];
NSLog(#" text message is : %#",[cell.btnContent titleForState:UIControlStateNormal]);
cell.btnContent.tag = indexPath.row;
return cell;
}
else
{
NSString *cellIdentifier;/* = isOutgoingMessage ? self.outgoingCellIdentifier : self.incomingCellIdentifier;*/
if ([[self.arrTableData objectAtIndex:indexPath.row] isKindOfClass:[OTRVoice class]])
{
OTRVoice *voice = (OTRVoice *)[self.arrTableData objectAtIndex:indexPath.row];
if(![voice.fk_Tripper isEqualToString:appDelegate.account.uniqueId])
{
cellIdentifier = self.incomingCellIdentifier;
}
else
{
cellIdentifier = self.outgoingCellIdentifier;
}
}
else{
cellIdentifier = self.outgoingCellIdentifier;
}
#try
{
VoiceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell.avatarImage.clipsToBounds = YES;
cell.avatarImage.layer.cornerRadius = cell.avatarImage.bounds.size.width / 2.0;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
tableview.separatorStyle = UITableViewCellSeparatorStyleNone;
cell.circular_ProgressView.frame = CGRectMake(cell.btnPlay.frame.origin.x-2, cell.btnPlay.frame.origin.y, 26, 26);
[self configureCell:cell atIndexPath:indexPath];
cell.tag = indexPath.row +10000;
return cell;
}
#catch(NSException *e)
{
NSLog(#"Exception is : %#",e);
}
}
}
you can use https://github.com/rs/SDWebImage library.
In this lib you can set the image directly to UIImageview using lazy loading concept. So even if you set image every time. it will not download again and again.
check the below code for example.
NSURL *url = [NSURL URLWithString:#"url"];
[cell.avatarImage setImageWithURL:url usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
I've a problem, when I'm refreshing my tableView more then 5-6(+/-) times in a row, I'm having exec bad access in the following methods:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *messages = [HumanResponse allAcceptedRecords];
if (messages != nil && messages.count > 0) {
CoreDataPhotoRecord *photoDetails = (CoreDataPhotoRecord *)messages[indexPath.row];
if (photoDetails != nil) {
==> HERE==> if (photoDetails.message != nil) {
if (photoDetails.message.flag.integerValue == FLAG_NOT_HANDLED) {
return YES;
}
}
}
}
return NO;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id globalCell;
CoreDataPhotoRecord *photoDetails = nil;
if (self.searchDisplayController.isActive) {
photoDetails = self.searchResults[indexPath.row];
}
else {
NSArray *results = [HumanResponse allAcceptedRecords];
if (results.count > 0) {
photoDetails = results[indexPath.row];
}
}
==> HERE==> if (photoDetails != nil && photoDetails.message != nil && [self isNormanMessageCell:photoDetails.message.type.integerValue]) {
MessageCell *cell = (MessageCell *)[tableView dequeueReusableCellWithIdentifier:kMessageCellID
forIndexPath:indexPath];
if (cell == nil) {
cell = (MessageCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:kMessageCellID];
}
if (tableView.isEditing) {
[cell setSelectionStyle:UITableViewCellSelectionStyleDefault];
} else {
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
And Related Method (I guess):
+ (NSArray *)allAcceptedRecords
{
// Permanent
NSArray *results = [CoreDataPhotoRecord MR_findAllSortedBy:#"message.originalDate"
ascending:NO
withPredicate:[NSPredicate predicateWithFormat:#"message.delete_message == %#", #NO]];
return results;
}
I don't know what is wrong here since I'm always checking if this variable is not nil, so it keep crashing?
As I said, for the first 5-6 times(+/-), it doesn't crash but trying once again right after will make it crash.
An I missing something?
i need to add checkmark when we tap on each cell, and it must show when i return back to tableview.
I tried with this code but its not working,
- (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];
}
if (self.thread == nil) {
cell.textLabel.text = #"Loading, please wait...";
} else if ([self.thread count] == 0) {
cell.textLabel.text = #"No Results!";
} else {
//
NSDictionary *msg = [self.thread objectAtIndex:indexPath.row];
NSLog(#"yourMutableDictionary - %#",msg);
if (indexPath.row == 0) {
cell.textLabel.text = [thread objectAtIndex:0];
} else {
cell.textLabel.text = [NSString stringWithFormat:#"%# ", [msg objectForKey:#"id"]];
if ([self.idSelected count] != 0) {
if ([self.idSelected containsObject:[NSString stringWithFormat:#"%#", [msg objectForKey:#"id"]]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
}
}
return cell;
}
#pragma mark - Table view delegate
//In a xib-based application, navigation from a table can be handled in - tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path
{
if (self.thread == nil || self.thread.count == 0) {
return;
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (path.row == 0) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;// this checkmark not working
}
else {
NSDictionary *user = [self.thread objectAtIndex:path.row];
NSString *uName = [NSString stringWithFormat:#"%# %#", [user objectForKey:#"first_name"], [user objectForKey:#"last_name"]];
NSString *uId = [NSString stringWithFormat:#"%#",[user objectForKey:#"id"]];
NSLog(#" click id%#", uId);
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
[userNames removeObject:uName];
[userIds removeObject:uId ];
cell.accessoryType = UITableViewCellAccessoryNone; // this check mark is working perfectly
} else {
[userNames addObject:uName];
[userIds addObject:uId];
cell.accessoryType = UITableViewCellAccessoryCheckmark; // this check mark is working perfectly
}
}
}
first cell check mark is not working but others working perfectly. I want to add check mark on first cell too, how its possible
Use below code to display checkmark on multiple table view cell :
- (void)viewDidLoad
{
[super viewDidLoad];
self.arraySelectedCell = [NSMutableArray array];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.arraySelectedCell containsObject:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
// do here..
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//the below code will allow multiple selection
if ([self.arraySelectedCell containsObject:indexPath])
{
[self.arraySelectedCell removeObject:indexPath];
}
else
{
[self.arraySelectedCell addObject:indexPath];
}
[tableView reloadData];
}
happy coding!
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;
}
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.