Loading thumbnail image in tableView - ios

I have a UITableView within a UIViewController and I'm trying to load the imageFile as a thumbnail in my UITableViewCell. All UITableViewCell data is being loaded from parse and i can successfully load the NSObject name and username into the UITableViewCell but for some reason im getting an error with the thumbnial image. my code is as follows (for cell).
#pragma mark - Table view data source
- (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 self.groups.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
PFObject *group = [self.groups objectAtIndex:indexPath.row];
PFFile *thumbnail = [group objectForKey:#"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.layer.cornerRadius = thumbnailImageView.frame.size.width/2;
thumbnailImageView.layer.masksToBounds = YES;
thumbnailImageView.image = [UIImage imageNamed:#"cc"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [group objectForKey:#"name"];
UILabel *usernameLabel = (UILabel*) [cell viewWithTag:103];
usernameLabel.text = [group objectForKey:#"creatorName"];
return cell;
}

It seems that [cell viewWithTag:100] is a UIImageView in storyboard. Try to set the UIImageView class to PFImageView in identity inspector, hope this would solved your problem too.
Good luck

You are assigning object to PFFile:
The correct usage of PFFile is:
PFFile *thumbnail = [PFFile fileWithName:fileName data:fileData];
The correct usage of PFObject is:
PFObject *group = [PFObject objectWithClassName:#"your class name"];

Related

How to add images to UITableView from phone gallery

I created in storyboard UITableView with prototype cell, TableViewController and UITableViewCell. Now I would like to choose all the pictures from phone gallery and save one or more to the database. But at this moment I need to implement adding pictures to tableview. I'm beginner in iOS. Can anyone tell me how can do that? give me a link or code? Thank you for advance
You can use ALAssetsLibrary in AssetsLibrary framework to fetch all images from phone gallery. Save each images in to an Array.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
NSURL *url= (NSURL*) [[result defaultRepresentation] url];
[library assetForURL:url
resultBlock:^(ALAsset *asset) {
UIImage *img = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]];
[imgArray addbject:img];
}
failureBlock:^(NSError *error){ NSLog(#"operation failed"); } ];
}
}
};
Then you can use this array for saving to DB or to show in tableview.
For Using in TableView, you need to add UIImageView in your prototype cell, then set the images from the array to the cell accordingly. Your table view delegate methods will be like below.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [imgArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CellId = #"ImageCell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellId];
}
UIImage *img = [imgArray objectAtIndex:indexPath.row];
cell.imgView.image = img;
return cell;
}
If you want to pick the image from gallery and show it to tableview, you can use Custom ImageView in tableView or CustomCell imageView
First you need to pick the image from gallery and save it to array
Before that allocate and initialize the array in viewDidLoad method
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrayImage;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
arrayImage = [[NSMutableArray alloc]init];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image=[info objectForKey:#"UIImagePickerControllerOriginalImage"];
imageView.image=image;
[arrayImage addObject:image];
picker.delegate =self;
[picker dismissViewControllerAnimated:YES completion:nil];
}
Then in tableView
If you CustomCell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell==nil)
{
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:#"CustomTableViewCell" owner:self options:nil];
cell = nib[0];
}
cell.galleryImageView.image = [arrayImage objectAtIndex:indexPath.row];
return cell;
}
If you use default table view cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:strCell];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
cell.imageView.image = [arrayImage objectAtIndex:indexPath.row];
return cell;
}

UItableView deplicated cell when scrolling

Sorry for posting this question again but I've looked into many answers and neither of them was helpfull to solve my issue.
So this my code :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"radioCell";
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
[self configureCommentCell:cell atIndexPath:indexPath];
return cell;
}
when I scroll down my cell get mixed up and some of data are repeated, so I've tried this :
static NSString *CellIdentifier = #"memberCell";
RadioCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
and this :
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
}
But it didn't fixed my issue and I get white empty cells ? please how to fix this issue ?
Update
- (void)configureCommentCell:(RadioTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object;
if ([_dataArray[indexPath.section] isKindOfClass:[NSArray class]])
object = [_dataArray[indexPath.section] objectAtIndex:indexPath.row];
else
object = [[_dataArray[indexPath.section] valueForKey:#"radioList"] objectAtIndex:indexPath.row];
if (object[#"jsonUrl"]) {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:object[#"jsonUrl"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
//NSDictionary *tempObject = (NSDictionary *) responseObject;
if (![[responseObject objectForKey:#"type"] isEqualToString:#"error"]) {
NSDictionary *tempObject = [responseObject[#"data"] objectAtIndex:0];
cell.playingNow.text = tempObject[#"song"];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
cell.name.text = [NSString stringWithFormat:#" %#", object[#"title"]];
if (object[#"logoUrl"])
[cell.logo setImageWithURL:[NSURL URLWithString:object[#"logoUrl"]]];
}
I see that your problem is that you are fetching the data of you cells inside configureCommentCell that's called inside cellForRowAtIndexPath. which is wrong, because it too late to fetch data inside cellForRowAtIndexPath, in this delegate method you should return the cell.
this line may be called before retrieving the data from server :
cell.name.text = [NSString stringWithFormat:#" %#", object[#"title"]];
Instead you should:
Fetch the data inside a separate method for example fetchData
when the data is downloaded inside the completion block of AFNetworking method, store the data inside an NSArray called for example myDataArray still inside the completion block call [self.tableView reloadData];
In viewDidLoad method just call your method fetchData
And your cellForRowAtIndexPath should looks like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// hey please give me the cell to display ... harry up please
// please harry up ! oh my god you are fetching data from server
// while I am asking for the cell !
// ok I don't care do what you want
// I will return an empty cell anyway
// and guess what I will not take in consideration
// the retried data because it's inside a block
// which is called asynchronously
static NSString *cellIdentifier = #"radioCell";
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; }
// now before return the cell you need to update the content of cell
// maybe you have an array of items and you should update the label
// for example here and then return the cell
cell.usernameLabel = self.myDataArray[indexPath.row]; // example
return cell;
}
Well the TableView is reusing the cells, and you add the image every time a cell is displaid. Thus when reusing the cell you add an other image, but there already is an image.
You will have to reuse the image view, and only add the image if you create the cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifer = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifer];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifer]autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20,0,30,44)];
imageView.tag = 1001;
[cell addSubview:imageView];
[imageView release], imageView= nil;
}
TabBarTestAppDelegate *delegate = (TabBarTestAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *local = delegate.myData;
// ok, it's horrible, don't look at it :-)
cell.textLabel.text = [NSString stringWithFormat:#"%#%#", #" " ,[local objectAtIndex:indexPath.row]];
//
NSString* name = nil;;
if (indexPath.row == 0) {
name = #"topicon";
}
else if (indexPath.row + 1 == [local count]) {
name = #"bottomicon";
}
else {
name = #"innericon";
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:1001];
imageView.image = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:name ofType:#"png"]];
return cell;
}

Loading images in each section

I am currently using Parse as my back end and have a few photos stored on their servers. When I go to query them into my table view, every section comes up with the same image over and over again instead of having different images for each user. I will post my code for the cellForRowAtIndexPath I just don't understand what is going on. And each section has it's own header to display the user's name who posted the image.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger sections = self.userPhotos.count;
return sections;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cellIdentifier";
HomeViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[HomeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Setting the image in the cell.
PFObject *carPhoto = [self.userPhotos objectAtIndex:indexPath.row];
PFFile *imageFile = [carPhoto objectForKey:#"imageFile"];
NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
cell.carImage.contentMode = UIViewContentModeScaleAspectFit;
cell.carImage.image = [UIImage imageWithData:imageData];
return cell;
}
Thank you for your help in advance!

How to use to two cell identifiers to sort data?

com documentation, and I am using the PFQueryForTable method with two different tableViewCells to sort my parse objects when they are put into the cells. I am doing this so when the object returns a blank string I can reduce its height to 0. Unfortunately when I do this it does not run like I want to and the blank cells are loaded into the first first cell, and not the one that I want to reduce the height to.
My cellForRowAtIndexPath looks like:
-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
BOOL blank = [[[object objectForKey:#"post"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:#""];
static NSString *CellIdentifier = #"Cell";
static NSString *Cell2Identifier = #"Cell2";
if (!blank) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
label.text = [object objectForKey:#"post"]; //[object objectForKey:#"post"];
label.textAlignment = NSTextAlignmentCenter;
NSLog(#"posted cell");
return cell;
}
else {
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:Cell2Identifier forIndexPath:indexPath];
if (cell2 == nil) {
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cell2Identifier];
}
cell2.textLabel.text = [object objectForKey:#"post"];
NSLog(#"posted cell2");
return cell2;
}
}
Can someone please point me in the right direction?
Thank you.
OK, from your comment you are currently creating a query like this...
- (PFQuery *)theQuery
{
PFQuery *posts = [PFUser query];
[posts whereKey:#"location" nearGeoPoint:self.myLocation withinKilometers:10.0];
[posts includeKey:self.textKey];
return posts;
}
So all you need to do is add another where condition to it...
[posts whereKey:#"theText" notEqualTo:#""];
This will stop blank text posts from being sent down.

Autoresizing UITableViewCell

I wan to know how can I resize my table view cell, and see all the message
My app is obtaining the messages from an xml on my server, and then it shows them, but if the message is longer than the text field it just display 3 dots
here is my code:
- (NSInteger)tableView:(UITableView *)myTableView numberOfRowsInSection:(NSInteger)section {
return ( messages == nil ) ? 0 : [messages count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 37;
}
- (UITableViewCell *)tableView:(UITableView *)myTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[self.messageList dequeueReusableCellWithIdentifier:#"ChatListItem"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatListItem" owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
textLabel.text = [itemAtIndex objectForKey:#"text"];
UILabel *stextLabel = (UILabel *)[cell viewWithTag:3];
stextLabel.text = [itemAtIndex objectForKey:#"text"];
UILabel *userLabel = (UILabel *)[cell viewWithTag:2];
userLabel.text = [itemAtIndex objectForKey:#"user"];
UILabel *suserLabel = (UILabel *)[cell viewWithTag:4];
suserLabel.text = [itemAtIndex objectForKey:#"user"];
if ([usernameText.text isEqualToString:userLabel.text]){
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"chat1#2x.png"]];
[cell setBackgroundView:img];
[img release];
textLabel.hidden=NO;
stextLabel.hidden=YES;
userLabel.hidden=NO;
suserLabel.hidden = YES;
}
else{
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"chat2#2x.png"]];
[cell setBackgroundView:img];
[img release];
textLabel.hidden=YES;
stextLabel.hidden=NO;
userLabel.hidden=YES;
suserLabel.hidden = NO;
}
return cell;
}
Thanks
You have to pass by heightForRowAtIndexPath like this logic (isn't a code ready):
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
NSString *text = [itemAtIndex objectForKey:#"text"];
if(text is larger then what ever you want) {
return yourSpecificCellHeight;
}
return 37;
}
To calculate the size of text see this post on stackOverflow

Resources