Best Way utilize PHPhotoLibrary for display Camera Roll image in UICollectionView with custom Cell - objective-c

Hello everyone I have a problem with my app ... Within my View Controller hp a CollectionView with a custom cell that should return all of the photos in the Camera Roll section of the app pictures of my iphone.
Now I've done all the steps to show the photos in a ImageView in the custom cell and up to now I have no problem ... My problem is that when I start to scroll through photos, uploading photos is very slow and immediately after the app crashes giving me back this error in the log ..
[GatekeeperXPC]
Connection to assetsd was interrupted or assetsd died 25/02/2017 20:
[Generic] Creating an image
format with an unknown type is an error
Can you tell me if I've taken the right way to show pictures in my collection view? Where did I go wrong? because my app crashes?
Thank you all for any help you can give me
This is the code i utilize
- (void)viewDidLoad {
[super viewDidLoad];
self.nameTextField.delegate = self;
self.emailTextField.delegate = self;
self.passwordTextField.delegate = self;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
_collectionView.backgroundColor = [UIColor clearColor];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_nameTextField becomeFirstResponder];
[self queryImage];
}
-(void)queryImage {
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
PHFetchResult *collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:fetchOptions];
if (collection.firstObject != nil ) {
_photoFound = YES;
_assetCollection = collection.firstObject;
} else {
}
_photoAsset = [PHAsset fetchAssetsInAssetCollection:_assetCollection options:nil];
[_collectionView reloadData];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(80,80);
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSUInteger count = 0;
if (_photoAsset != nil) {
count = [_photoAsset count];
}
return count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *reuseIdentifier = #"imageCell";
UPCameraRollCollectionViewCell* cell = [cv dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
PHAsset *asset = [_photoAsset objectAtIndex:indexPath.item];
PHImageManager *imageManager = [PHImageManager defaultManager];
[imageManager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
[cell setThumbnailImage:result];
}];
return cell;
}

Use PHCachingImageManager.
Apple has an example that shows exactly how to do the sort of thing you're after. Collection views are precisely the intended use case.

Related

Set TV Menu Button To Go Back One Screen

My Apple TV app lists a collection of PDFs, and clicking one draws it on the screen. For some reason, though, it exits the app completely when someone hits the < / Menu button on the Apple TV Remote. What is going on to cause it to do that?
Up first is the code where it pulls up the list of all the PDFs, followed by the code for displaying the PDF.
-(void)viewDidLoad {
[super viewDidLoad];
self.definesPresentationContext = YES; // know where you want UISearchController to be displayed
}
- (void)viewWillAppear:(BOOL)animated {
if (self.searchControllerWasActive) {
self.searchController.active = self.searchControllerWasActive;
_searchControllerWasActive = NO;
if (self.searchControllerSearchFieldWasFirstResponder) {
[self.searchController.searchBar becomeFirstResponder];
_searchControllerSearchFieldWasFirstResponder = NO;
}
}
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:#"pdf" inDirectory:#"AIMPDF"];
NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
self.title = #"Devo Songs";
self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
NSLog(#"%#", filenames);
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *path in self.files) {
[names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
self.files = names;
self.files = [names sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
self.tableView.backgroundColor = [UIColor whiteColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"iphonebackground.png"]];
[super viewDidLoad];
[super viewWillAppear:animated];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// update the filtered array based on the search text
NSString *searchText = searchController.searchBar.text;
NSMutableArray *searchResults2 = [self.files mutableCopy];
// strip out all the leading and trailing spaces
NSString *strippedString = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// break up the search terms (separated by spaces)
NSArray *searchItems = nil;
if (strippedString.length > 0) {
searchItems = [strippedString componentsSeparatedByString:#" "];
}
// build all the "AND" expressions for each value in the searchString
//
NSMutableArray *andMatchPredicates = [NSMutableArray array];
for (NSString *searchString in searchItems) {
NSPredicate *sPredicate =
[NSPredicate predicateWithFormat:#"SELF contains[c] %#", searchString];
[searchResults2 filterUsingPredicate:sPredicate];
// at this OR predicate to our master AND predicate
// NSCompoundPredicate *orMatchPredicates = [NSCompoundPredicate orPredicateWithSubpredicates:searchItemsPredicate];
//[andMatchPredicates addObject:orMatchPredicates];
}
// match up the fields of the Product object
// NSCompoundPredicate *finalCompoundPredicate =
//[NSCompoundPredicate andPredicateWithSubpredicates:andMatchPredicates];
//searchResults2 = [[searchResults filteredArrayUsingPredicate:finalCompoundPredicate] mutableCopy];
// hand over the filtered results to our search results table
APLResultsTableController *tableController = (APLResultsTableController *)self.searchController.searchResultsController;
tableController.filteredProducts = searchResults2;
[tableController.tableView reloadData];
}
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
array = nil;
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self files])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}- (void)viewDidUnload
{
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
// The device is an iPad running iPhone 3.2 or later.
return YES;
}
else
{
// The device is an iPhone or iPod touch.
return YES;
}
#else
// iPhone simulator
return YES;
#endif
}
#pragma mark -
#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.
NSInteger rows;
rows = [[self files] count];
return rows;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *filename = [[[self.files objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
NSInteger row = [indexPath row];
NSString *contentForThisRow = nil;
contentForThisRow = filename;
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setText:contentForThisRow];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica Neue" size:90];
cell.textLabel.textColor = [UIColor blackColor];
cell.backgroundColor = [UIColor lightGrayColor];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
return 80;
}
else {
return 120;
}
}
- (void)tableView:(UITableView *)tableView didUpdateFocusInContext:(UITableViewFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator
{
//this gives you the indexpath of the focused cell
NSIndexPath *nextIndexPath = [context nextFocusedIndexPath];
NSLog(#"Do Something");
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedCountry = (tableView == self.tableView) ?
self.files[indexPath.row] : self.resultsTableController.filteredProducts[indexPath.row];
[self performSegueWithIdentifier:#"ShowSong" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"ShowSong"])
{
NSLog(#"Selecting %#", self.selectedCountry);
FirstViewController* userViewController = [segue destinationViewController];
userViewController.selectedCountry = self.selectedCountry;
//if you need to pass data to the next controller do it here
}
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)dealloc {
}
#end
And now the code for opening:
#implementation FirstViewController
- (CGPDFDocumentRef)openPDFLocal:(NSString *)pdfURL {
NSURL* NSUrl = [NSURL fileURLWithPath:pdfURL];
return [self openPDF:NSUrl];
}
- (CGPDFDocumentRef)openPDFURL:(NSString *)pdfURL {
NSURL* NSUrl= [NSURL URLWithString:pdfURL];
return [self openPDF:NSUrl];
}
- (CGPDFDocumentRef)openPDF:(NSURL*)NSUrl {
CFURLRef url = (CFURLRef)CFBridgingRetain(NSUrl);
CGPDFDocumentRef myDocument;
myDocument = CGPDFDocumentCreateWithURL(url);
if (myDocument == NULL) {
NSLog(#"can't open %#", NSUrl);
CFRelease (url);
return nil;
}
CFRelease (url);
if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {
CGPDFDocumentRelease(myDocument);
return nil;
}
return myDocument;
}
- (void)drawDocument:(CGPDFDocumentRef)pdfDocument
{
// Get the total number of pages for the whole PDF document
int totalPages= (int)CGPDFDocumentGetNumberOfPages(pdfDocument);
self.pages = totalPages;
NSMutableArray *pageImages = [[NSMutableArray alloc] init];
// Iterate through the pages and add each page image to an array
for (int i = 1; i <= totalPages; i++) {
// Get the first page of the PDF document
CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, i);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
// Begin the image context with the page size
// Also get the grapgics context that we will draw to
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// Rotate the page, so it displays correctly
CGContextTranslateCTM(context, 0.0, pageRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page, kCGPDFMediaBox, pageRect, 0, true));
// Draw to the graphics context
CGContextDrawPDFPage(context, page);
// Get an image of the graphics context
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[pageImages addObject:image];
}
// Set the image of the PDF to the current view
[self addImagesToScrollView:pageImages];
}
-(void)addImagesToScrollView:(NSMutableArray*)imageArray {
int heigth = 0;
for (UIImage *image in imageArray) {
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
imgView.frame=CGRectMake(200, heigth, 1520, 1080);
[_scrollView addSubview:imgView];
heigth += imgView.frame.size.height;
}
}
-(void)viewDidLayoutSubviews {
NSLog(#"%ld", (long)self.pages);
_scrollView.contentSize = CGSizeMake(1920, 1080*self.pages);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"DOCUMENTS%#", self.selectedCountry);
NSString *testing = [self.selectedCountry stringByAppendingString:#".pdf"];
//This is passed in from a tableview after selecting the PDF needed.
_scrollView.panGestureRecognizer.allowedTouchTypes = #[ #(UITouchTypeIndirect) ];
NSString *Documents = [[NSBundle mainBundle] pathForResource:self.selectedCountry ofType:#"pdf" inDirectory:#"AIMPDF"];
NSLog(#"OKOKOK%#", Documents);
NSURL *url = [NSURL fileURLWithPath:Documents];
self.view.backgroundColor = [UIColor blackColor];
CGPDFDocumentRef pdfDocument = [self openPDF:url];
[self drawDocument:pdfDocument];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
In your case the searching view controller stays on the top level of your app that's why the app is closed by pressing Menu button instead of returning to your start screen. On tvOS you should not use UISearchController directly and call
[self.searchController.searchBar becomeFirstResponder]; or self.searchController.active = YES; to present searching because it breaks a stacked view hierarchy that allows you to navigate upper by presented view controllers.
On Apple TV, people typically navigate by moving through stacked screens of content. Each screen may present entry points to other screens, and provides a way — through the remote — to return to the previous screen or main menu.
https://developer.apple.com/design/human-interface-guidelines/tvos/app-architecture/navigation/
There is UISearchContainerViewController view controller that manages the presentation of search results in your interface and you can use it for searching:
In tvOS, rather than push a UISearchController onto a navigation controller’s stack or use one as a child of another container view controller, embed an instance of this class and let it manage the presentation of the search controller’s content. https://developer.apple.com/documentation/uikit/uisearchcontainerviewcontroller
For instance:
UITableViewController* searchTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SearchTableViewController"];
UISearchController* searchController = [[UISearchController alloc] initWithSearchResultsController:searchTableViewController];
searchController.delegate = self;
searchController.searchResultsUpdater = self;
searchController.searchBar.delegate = self;
self.searchContainerViewController = [[UISearchContainerViewController alloc] initWithSearchController:searchController];
// Show searching
[self presentViewController:self.searchContainerViewController animated:YES completion:nil];

Reload data in tableview while scrolling with API

how to reload the data in the table while scrolling?
If i have a url "http:.......&start=0&limit=50".
How to reload the data in table with incrementing the start and limit value with 50.
Can anyone find a solution for this?
You need to implement the load more functionality in the table view for this.In order to do so, you need to track the table view's index while it is scrolling once table reaches the last cell you can call the api with increased page number and add the new records to the array once you get the positive response from the api.
See the below code for more understanding.
Variable initialization
#interface ExampleListVC (){
BOOL hasNextPage,isLoadingNextPage;
int currentPage;
NSMutableArray *arrTableData;
}
#end
In viewDidLoad method
arrTableData = [[NSMutableArray alloc]init];
currentPage=-1;
hasNextPage = YES;
In tableView numberOfRowsInSection method
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = (int)arrTableData.count;
if (hasNextPage)
{
count++;
}
return count;
}
In cellForRowAtIndexPath method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
if (indexPath.row<arrTableData.count)
{
//Load TableviewCell you intend to show
}
else
{
//Show loading cell
cell = [self loadingCell:indexPath];
if (!isLoadingNextPage)
{
[self fetchData];
}
}
return cell;
}
Loading Cell Code
-(UITableViewCell *) loadingCell :(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:nil];
cell.backgroundColor = [UIColor clearColor];
UIActivityIndicatorView *activityIndicatorView =[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicatorView.color = [UIColor blackColor];
activityIndicatorView.center = CGPointMake(self.tblView.center.x, cell.center.y);
[cell.contentView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];
cell.userInteractionEnabled = NO;
return cell;
}
Api call implementation
-(void)fetchData
{
isLoadingNextPage = YES;
if (currentPage==-1)
currentPage=0;
//API Call
{
DLog(#"API Call Response = %#",response);
isLoadingNextPage = NO;
if (response == nil)
{
hasNextPage=NO;
return;
}
if (success)
{
if (hasNextPage)
{
currentPage++;
}
[arrTableData addObjectsFromArray:response];
}
else
{
hasNextPage=NO;
}
//Reload tableview
}];
}
Alternative solution for this is
Use the SVPullToRefresh library in integrate infinite scrolling of it.
https://github.com/samvermette/SVPullToRefresh
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(self.comptabl.contentOffset.y >= (self.comptabl.contentSize.height - self.comptabl.bounds.size.height))
{
if(isPageRefreshing==NO){
isPageRefreshing=YES;
[appDelegate showIndicator:nil view1:self.view];
start=start+50;
[self makeRequest:start];
[self.comptabl reloadData];
NSLog(#"called %d",start);
}
}
}
I am using this method but at all time the value is increment with 50 ..how can i set limit to the value

UICollectionView not showing images from CameraImage - Objective C

Searched the forum and could not find a suitable answer that works. I suspect something is wrong with the code. I am taking pictures with a camera and trying to show them in a UICollectionView. The collectionView has a cell with a UIImageView inside of it.
Even when setting a static image and background colour I still don't see anything (not even the colour).
Code is as follows:
#import "CameraPageViewController.h"
#interface CameraPageViewController ()
#end
#implementation CameraPageViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_imageList = [[NSMutableArray alloc] init];
_collectionView.delegate = self;
_collectionView.dataSource = self;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"PictureCell"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)takePhoto:(id)sender {
UIImagePickerController *imagePickController=[[UIImagePickerController alloc]init];
imagePickController.sourceType=UIImagePickerControllerSourceTypeCamera;
imagePickController.delegate=self;
imagePickController.allowsEditing=TRUE;
[self presentViewController:imagePickController animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
UIImage *chosenImage = editingInfo[UIImagePickerControllerOriginalImage];
[_imageList addObject:chosenImage];
[self dismissViewControllerAnimated:YES completion:nil];
[_collectionView reloadData];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.imageList count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"PictureCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *pictureView = (UIImageView *) [cell viewWithTag:110];
NSInteger rowValue = indexPath.row;
UIImage *currentImage = [_imageList objectAtIndex:indexPath.row];
pictureView.image = currentImage;
return cell;
}
#end
i think u might missed the setting the layout for your collection view set it and try
- (void)viewDidLoad
{
[super viewDidLoad];
//...other code
_imageList = [[NSMutableArray alloc] init];
//set layout hear
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; //default layout
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.minimumInteritemSpacing = 0.0f;
flowLayout.minimumLineSpacing = 0.33f; //set the offset between items
_collectionView.showsHorizontalScrollIndicator = NO;
_collectionView.showsVerticalScrollIndicator = NO;
[_collectionView setCollectionViewLayout:flowLayout];
_collectionView.delegate = self;
_collectionView.dataSource = self;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"PictureCell"];
}
//implement this delegate method to return item size for each cell
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(200.0f,300.0f);
}
Fixed it by adding the images as sub views through the code instead of the story board. No idea why it works, but it did.

Remove UICollectionView cells on edit button

I am using a UICollectionView to retrieve images and labels stored in the Cloud database Parse.
I now need an option that will let me delete a certain image and its corresponding label.
I am looking for something such as the typical iPhone "Edit" button on the top right hand corner which displays a swipe animation with a delete button next to the cell. I'm aware that such a thing can be done on a UITableView through
[[self tableView] setEditing:YES animated:YES];
but I can't seem to find the equivalent for a UICollectionView anywhere.
Any help appreciated, even if it doesn't deal with the deletion from Parse itself, just the editing style on the collection view would be ideal.
Here is how I populate my cells:
- (void)viewDidLoad
{
[super viewDidLoad];
[self retrieveSelectedImages];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [imageFilesArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"myRoomsCell";
MyRoomsCell *cell = (MyRoomsCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
PFObject *imageObject = [imageFilesArray objectAtIndex:indexPath.row];
PFFile *imageFile = [imageObject objectForKey:#"imageFile"];
cell.loadingSpinner.hidden = NO; //show loading spinner to indicate work is happening until the image loads
[cell.loadingSpinner startAnimating];
// UILabel *label = (UILabel*) [cell viewWithTag:5];
cell.label.text= [imageObject objectForKey:#"roomLabel"]; //set room label as the label stored on parse previously inserted by the user
cell.label.font = [UIFont fontWithName:#"Helvetica-Bold" size:18];
cell.label.textAlignment = NSTextAlignmentCenter;
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error)
{
if (!error) {
cell.parseImage.image = [UIImage imageWithData:data];
[cell.loadingSpinner stopAnimating];
cell.loadingSpinner.hidden = YES;
}
}];
return cell;
}
-(void) retrieveSelectedImages
{
//parse query where we search the favorites array column and return any entry where the array contains the logged in user objectid
PFQuery *getFavorites = [PFQuery queryWithClassName:#"collectionViewData"];
[getFavorites whereKey:#"selectedImage" equalTo:[PFUser currentUser].objectId];
[getFavorites findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
imageFilesArray = [[NSArray alloc] initWithArray:objects];
[roomsCollection reloadData];
}
}];
}
Check out this answer with plenty of code for you to try out: https://stackoverflow.com/a/16190291/1914567
Basically, there is no Apple-provided way to do this.
There are also some really nice libraries. My personal favorite is DraggableCollectionView, and also check out LXReorderableCollectionViewFlowLayout.
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[[Singleton sharedSingleton].selectedProfileArray removeObjectAtIndex:indexPath.row];
[selectCollectionView reloadData];
}

Getting profile image in iOS via STTwitter

I am using the the STTwitter API to make an App only twitter Feed. I have successfully output the tweet to the table cell, but now I'm attempting to connect user profile images and I am running in to some problems. I tried implementing the code I found here, but I was getting an error stating "No known class method for selector 'imageWithContentsOfURL:'" so I fixed the problem by replacing UIImage with CIImage. However, now my app is crashing because I'm trying to output a CIImage to an UIImageView. My code and errors are as follows:
Code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* boldFontName = #"Avenir-Black";
[self styleNavigationBarWithFontName:boldFontName];
self.title = #"Twitter Feed";
self.feedTableView.dataSource = self;
self.feedTableView.delegate = self;
self.feedTableView.backgroundColor = [UIColor whiteColor];
self.feedTableView.separatorColor = [UIColor colorWithWhite:0.9 alpha:0.6];
//self.profileImages = [NSArray arrayWithObjects:#"profile.jpg", #"profile-1.jpg", #"profile-2.jpg", #"profile-3.jpg", nil];
STTwitterAPI *twitter = [STTwitterAPI twitterAPIAppOnlyWithConsumerKey:#"stuff"
consumerSecret:#"stuff"];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
[twitter getUserTimelineWithScreenName:#"RileyVLloyd"
successBlock:^(NSArray *statuses) {
self.twitterDataSource = [NSMutableArray arrayWithArray:statuses];
for (int i=1; i <= _twitterDataSource.count; i++) {
NSLog(#"%d", i);
NSDictionary *tweetDictionary = self.twitterDataSource[i];
NSString *final = tweetDictionary[#"profile_image_url"];
NSLog(#"%#", final);
}
[self.feedTableView reloadData];
} errorBlock:^(NSError *error) {
NSLog(#"%#", error.debugDescription);
}];
} errorBlock:^(NSError *error) {
NSLog(#"%#", error.debugDescription);
}];
//[self getTimeLine];
}
#pragma mark Table View Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.twitterDataSource.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"FeedCell3" ;
FeedCell3 *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[FeedCell3 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.nameLabel.text = #"RileyVLloyd";
cell.likeCountLabel.text = #"293 likes";
cell.commentCountLabel.text = #"55 comments";
//NSString* profileImageName = self.profileImage[indexPath.row%self.profileImage.count];
cell.profileImageView.image = _profileImage;
NSInteger idx = indexPath.row;
NSDictionary *t = self.twitterDataSource[idx];
cell.updateLabel.text = t[#"text"];
cell.dateLabel.text = #"1 day ago";
return cell;
}
An easier way to accomplish this would be to use the SDWebImage API. The API asynchronously loads the image, so then you won't have to worry about loading due to the main thread being used for loading the images. Also, this API only requires a couple lines of code below to be added to your UITableViewCell method.
NSString *aURL = t[#"user"][#"profile_image_url"];
[cell.profileImageView setImageWithURL:[NSURL URLWithString:aURL]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Your code does crash because you're trying to get a value for the key profile_image_url on username which is a string, hence the exception <__NSCFString ...> is not key value coding-compliant for the key profile_image_url.
Let's assume that what you really want to do here is retrieving the images for each tweet author.
You have to iterate over the statuses and, for each of them, extract the profile_image_url and create a UIImage with it.