Sometimes when i go to my collectionView, its blank - ios

i have everything working it seems, but i noticed sometimes when i go to the collection view, its blank, but when i refresh it, everything is loaded and shown.
here is my cellForItemAtIndexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const reuseIdentifier = #"imageCell";
imageCollectionCell *cell = [self.myCollectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
PFFile *imageFile = [imageObject objectForKey:#"image"];
[imageFile getDataInBackgroundWithBlock:^(NSData * _Nullable data, NSError * _Nullable error) {
if (!error) {
cell.imageViewCell.image = [UIImage imageWithData:data];
cell.imageViewCell.contentMode UIViewContentModeScaleAspectFill;
}
else{
NSLog(#"Fail");
}
} progressBlock:^(int percentDone) {
}];
return cell;
}
here is my query for the collectionview
- (void) queryData {
imageCollectionCell *cell = (imageCollectionCell *)[self.myCollectionView cellForItemAtIndexPath:[[self.myCollectionView indexPathsForSelectedItems] firstObject]];
cell.imageViewCell.image = nil;
NSLog(#"initiated");
[self.refreshControl endRefreshing];
PFObject *queryPhotos = self.userInformationObject;
PFQuery *query = [PFQuery queryWithClassName:#"Photo"];
[query whereKey:#"userTookPhoto" equalTo:queryPhotos];
[query orderByAscending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error)
{
if (!error) {
NSLog(#"Query no error");
imageFilesArray = [[NSArray alloc] initWithArray:objects];
}
}];
[self.myCollectionView reloadData];
}

When you reload your collection view, you can't know if data are loaded.
So you must put your reload data in the completion block.

Related

When refreshing collectionView, it crashes because it doesnt update the numberOfItemsInSection

I have refresh method when user pulls down and it seems like it doesn't update the array count and just crashes:
Here is the crash:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 8]'
Here is my code:
Query Data: (used to refresh as well)
- (void) queryData
{
PFObject *queryPhotos = self.userInformationObject;
PFQuery *query = [PFQuery queryWithClassName:#"Photo"];
[query whereKey:#"userTookPhoto" equalTo:queryPhotos];
[query orderByAscending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (!error) {
imageFilesArray = [[NSArray alloc] initWithArray:objects];
[self.myCollectionView reloadData];
[self.refreshControl endRefreshing];
}
}];
}
CellForItemAtIndexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const reuseIdentifier = #"imageCell";
imageCollectionCell *cell = [self.myCollectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
cell.layer.borderColor = [UIColor grayColor].CGColor;
cell.layer.borderWidth = 0.5;
cell.layer.cornerRadius = 7.0f;
cell.clipsToBounds = YES;
PFObject *imageObject = [imageFilesArray objectAtIndex:indexPath.row];
PFFile *imageFile = [imageObject objectForKey:#"image"];
[imageFile getDataInBackgroundWithBlock:^(NSData * _Nullable data, NSError * _Nullable error) {
if (!error) {
cell.imageViewCell.image = [UIImage imageWithData:data];
}
else{
NSLog(#"Fail");
}
} progressBlock:^(int percentDone) {
}];
return cell;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
//#warning Incomplete implementation, return the number of sections
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
//#warning Incomplete implementation, return the number of items
return [imageFilesArray count];
}
This is all the code relating to the refresh, and showing the cells, I dont know whats going wrong, hope someone has an answer.
Thanks in advance.
Try below code.
- (void) queryData
{
[self.refreshControl endRefreshing];
PFObject *queryPhotos = self.userInformationObject;
PFQuery *query = [PFQuery queryWithClassName:#"Photo"];
[query whereKey:#"userTookPhoto" equalTo:queryPhotos];
[query orderByAscending:#"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
if (!error) {
imageFilesArray = [[NSArray alloc] initWithArray:objects];
}
}];
[self.myCollectionView reloadData];
}

iOS parse black strip on profile picture (PFImageView)

I am using Parse as a backend of my app, and it seems that the profile photo is not displaying properly, shown in the image:
there is a black strip on john_appleseed's photo.
here is my code for saving the profile image:
NSData *profileData = UIImagePNGRepresentation(cell1.profileView.image);
PFFile *profileFile = [PFFile fileWithName:#"profilePhoto" data:profileData];
[profileFile saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (!error)
{
if (succeeded)
{
[user setObject:profileFile forKey:#"profilePhoto"];
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
if (!error)
{
}
else
{
}
}];
}
}
}];
here is how I retrieve the image:(inside PFQueryTableViewController)
- (PFQuery *)queryForTable
{
//NSLog(#"called");
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString *filter = [defaults objectForKey:#"topicFilter"];
NSLog(#"queryfortable: %#", filter);
PFQuery *query = [PFQuery queryWithClassName:#"Questions"];
[query includeKey:#"user"];
[query whereKey:#"category" equalTo:filter];
[query orderByDescending:#"createdAt"];
return query;
}
- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == self.objects.count)
{
return nil;//this is for the load more cell.
}
return [self.objects objectAtIndex:indexPath.section];
}
in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
PFUser *user = [object objectForKey:#"user"];
PFImageView *profileImgView = (PFImageView *)[cell viewWithTag:1];
profileImgView.layer.cornerRadius = profileImgView.frame.size.height/2;
profileImgView.layer.masksToBounds = YES;
PFFile *file = user[#"profilePhoto"];
profileImgView.file = file;
[profileImgView loadInBackground];
any ideas? many thanks.
You should be updating user interfaces on the main thread. Since your loading something in the background, you should notify the main thread that it needs to update an object. loadInBackground is downloading the file asynchronously.
Here is an example, that you can alter for your needs, just to illustrate, that updating UI components in the call back has it's benefits; this is based off of Parses own AnyPic:
NSString *requestURL = file.url; // Save copy of url locally (will not change in block)
[file getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
//dispatch on main thread
UIImage *image = [UIImage imageWithData:data];
} else {
NSLog(#"Error on fetching file");
}
}];

How can I show a PFUser array of Parse in a UITableVIew in iOS?

I have tried following code so far:
PFGeoPoint * myGeoPoint = [PFUser currentUser][#"coordinates"]; // Your geoPoint
PFQuery *query = [PFUser query];
[query includeKey:#"User"];
[query whereKey:#"coordinates" nearGeoPoint:myGeoPoint withinMiles:radiusInMiles];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error){
for (PFUser *object in objects){
users = (NSArray*)[object ObjectForKey:#"User"];
}
[self.tableView reloadData];
}
}
}];
- (PFUser*) objectAtIndexPath:(NSIndexPath*)indexPath {
PFUser *object = [PFUser objectWithClassName: #"User"];
[object setObject:[users objectAtIndex:indexPath.row] forKey:#"User"];
return object;
}
// Use myObjects for numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
return users.count;
}
//Use your custom object for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath object:(PFUser *)object {
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell using object
UILabel *reviewLabel = (UILabel *)[cell viewWithTag:10];
reviewLabel.text = [object objectForKey:object.username];
PFFile *userImageFile = object[#"profilePic"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
if (imageData != nil)
cell.imageView.image = [UIImage imageWithData:imageData];
else cell.imageView.image= [UIImage imageNamed:#"defaultPerson"];
}
}];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SMChatViewController *chatController = [SMChatViewController alloc];
// [chatController initWithPhoto:image];
[self presentModalViewController:chatController animated:YES];
}
In this code I am retrieving an array of PFUsers as "objects".When I am saving the objects array to users it returns as empty. So can anyone please suggest me something that How can I set the username and profilepic in a tableView?
I guess query is not correct.
Try this:
PFGeoPoint * myGeoPoint = [PFUser currentUser][#"coordinates"]; // Your geoPoint
PFQuery *query = [PFQuery queryWithObject:#"_User"];
NSArray *userList = [NSArray new];
[query whereKey:#"coordinates" nearGeoPoint:myGeoPoint withinMiles:radiusInMiles];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error){
userList = objects;
[self.tableView reloadData];
}
}];
In your code you're asking 'User' objects, then you fetching 'User' field from this objects.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
PFUser *user = (PFUser*)[users objectAtIndex:indexPath.row];
cell.textLabel.text=user.username;
PFFile *userImageFile = user[#"profilePic"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
if (imageData != nil)
cell.imageView.image = [UIImage imageWithData:imageData];
else cell.imageView.image= [UIImage imageNamed:#"defaultPerson.png"];
}
}];
return cell;
}

how to put an Array of images into specific UICollectionViewCells

I'm currently developing a App thats home view controller shows a display of all the users friends, their names and their profile images (if they have one), each within a cell of a UICollectionView. I am using tags to identify the UI elements within each cell and Parse as the backend. Each user and their relations are stored under the class "User" and then their profile images (if they have chosen one/taken one) are stored under another class called "UserImage". I've managed to set their usernames to the cells but having difficulty with the images. Basically each cell is downloading the entire image array, which I believe is causing the app to crash with this error. Also as soon as the user adds a friend without a profile picture the app seems to act strange..
[__NSArrayM objectAtIndex:]: index 8 beyond bounds [0 .. 1]
here is how I save the image to parse.. This is in the users profile view controller.
-(void)uploadImage {
NSData *fileData;
NSString *fileName;
NSString *fileType;
UIImage *newImage = [self scaleImage:self.image toSize:CGSizeMake(340.0,340.0)];
fileData = UIImagePNGRepresentation(newImage);
fileName = #"profileimage.png";
fileType = #"profileimage";
PFFile *file = [PFFile fileWithName:fileName data:fileData];
[file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
PFUser *user = [PFUser currentUser];
PFObject *userImage = [PFObject objectWithClassName:#"UserImage"];
[userImage setObject:file forKey:#"file"];
[userImage setObject:fileType forKey:#"fileType"];
[userImage setObject:user forKey:#"user"];
[userImage saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error saving image");
}
else {
NSLog(#"Image Saved");
}
}];
}];
}
I then query for the current users relations within the viewWillAppear: method of the HomeViewController.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController.navigationBar setHidden:NO];
self.friendsRelation = [[PFUser currentUser] objectForKey:#"friendsRelation"];
self.friends = [[NSMutableArray alloc] init];
PFQuery *query = [self.friendsRelation query];
[query orderByAscending:#"username"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
else {
[self.friends addObjectsFromArray:objects];
[self.collectionView reloadData];
}
}];
}
Setting the amount of cells to the amount of the users friends..
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [self.friends count];
}
And finally setting up the cells within the cellForItemAtIndexPath: method
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
PFUser *user = [self.friends objectAtIndex:indexPath.row];
if (cell.tag == 0) {
UILabel *cellLabel = (UILabel *)[cell viewWithTag:25];
cellLabel.text = user.username;
PFImageView *homeImageView = (PFImageView *)[cell viewWithTag:50];
[homeImageView setContentMode:UIViewContentModeScaleAspectFill];
homeImageView.clipsToBounds = YES;
homeImageView.layer.cornerRadius = 7;
self.friendImages = [[NSMutableArray alloc] init];
PFQuery *imageQuery = [PFQuery queryWithClassName:#"UserImage"];
[imageQuery whereKey:#"user" containedIn:self.friends];
[imageQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
//need a statement that defines whether a friend has an image or not, if they do then load that image into their cell, if not then set default image
[self.friendImages addObjectsFromArray:objects];
PFObject *imageObject = [self.friendImages objectAtIndex:indexPath.row];
PFFile *imageFile = [imageObject objectForKey:#"file"];
homeImageView.file = imageFile;
[homeImageView loadInBackground];
NSLog(#"Retrieved %d images", [self.friendImages count]);
}
else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
return cell;
}
Any help would be appreciated! keep in mind I'm only a couple of weeks into learning iOS..

How can i retrieve a image from Parse.com via query at iOS?

I am using Parse.com for retrieving my data.I want to retrieve my images from parse via pf query but my approach does not working.I get nothing where my UIImageView is. Here is my code:
PFQuery *query = [PFQuery queryWithClassName:#"Class"];
[query whereKey:#"Yes or No" equalTo:[NSNumber numberWithBool:YES]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d scores.", objects.count);
for (int i = 0; i < objects.count; i++) {
object = [objects objectAtIndex:i];
NSString *Property1 = [object objectForKey:#"Property1"];
__block UIImage *MyPicture = [[UIImage alloc]init];
PFFile *imageFile = [object objectForKey:#"Resimler"];
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error){
if (!error) {
MyPicture = [UIImage imageWithData:data];
}
}];
aClass *AC = [[aClass alloc]initWithProperty:Propert1 Picture:MyPicture];
[self.MyArray addObject:AC];
}
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MyViewViewCell *cell = (MyViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
aClass *mC = [self.MyArray objectAtIndex:indexPath.row];
cell.Label.text = mC.Property;
cell.myImage.image = mC.Picture;
return cell;
}
Edit:
At aClass.h
#interface aClass : NSObject
#property(strong)NSString *Property;
#property(strong)UIImage *Resim;
-(id)initWithProperty:(NSString *)aProperty Picture:(UIImage *)aPicture ;
#end
at aClass.m
#implementation Mekan
#synthesize Property, Picture;
-(id)initWithMekanIsmi:(NSString *)aProperty Picture:(UIImage *)aPicture{
self=[super init];
if(self){
self.Property = aProperty;
self.Picture = aPicture;
}
return self;
}
#end
I know it is kind of a mass code but i have to write those codes to illustrate where i assign myImage. So you can ask where you do not understand
I do it like this:
UIImageView *imageView = [[UIImageView alloc] initWithImage:#"default.png"];
[userIcon getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
imageView.image = [[UIImage alloc] initWithData:data];
} progressBlock:^(int percentDone) {
// update progress
}];
You seem to be assigning it to a UIImage properly, but never setting that image as the image for a UIImageView.

Resources