UIImagePickerView blank images? - ios

I am instantiating a UIImagePicker like so:
self.picker = [[UIImagePickerController alloc] init];
[self.picker setDelegate:self];
[self.picker UIImagePickerControllerSourceTypePhotoLibrary];
[myVC presentViewController:self.picker animated:YES completion:nil];
And for some reason, it doesn't ask me for permission to view my images (on device, it is magically already allowed access (checked in Privacy settings)) and the images are blank. Yes, you heard correctly. Blank. They're completely white. However when I tap in a location where a image should be present, it shows the image in the editor view and displays the image.

Interestingly enough, this issue had nothing to do with NavigationControllers, UIImages/ImageViews or even ViewControllers. I had a category on NSDictionary that overrode objectForKeyedSubscript. I guess users images are stored or retrieved in a Dictionary and when they tried to index into it for the UIImage, it failed somehow. Or maybe pulled a path that was nil.
The moral of this story is, BEWARE the CATEGORY.

Related

UIDocumentPickerViewController - possible to remember last import location/service?

When using UIDocumentPickerViewController for importing data into my app, I would like to remember the last service/location that was chosen by the user, and start the navigation with that service.
E.g. if a user imports something from Dropbox, and then later on wants to import something again, I would like the document picker to start with Dropbox as the initial location.
Unfortunately, the default behaviour is that the picker always starts with iCloud Drive, so each time a user wants to import something from Dropbox, they have to tap on Locations, and pick Dropbox from there - two unnecessary taps.
I've tried to keep a strong reference to a previously shown picker, but presenting that picker again doesn't seem to work - it just shows a blank view.
if(self.documentPicker) {
[self presentViewController:self.documentPicker animated:YES completion:nil];
return;
}
UIDocumentPickerViewController *vc =
[[UIDocumentPickerViewController alloc] initWithDocumentTypes:#[#"public.audio"] inMode:UIDocumentPickerModeImport];
vc.delegate = self;
self.documentPicker = vc;
[self presentViewController:vc animated:YES completion:nil];
There's also UIDocumentMenuViewController, which lets you choose a location/service up front and lets you then show the document picker which was chosen by it, but again, I have found no way to store a reference to a location with which to show a document picker in future import actions.
cheers!

How to display new ViewController on orientation change?

I'm trying to recreate an effect similar to the iOS Music app in that I want a completely new view to appear in my app when the phone flips from vertical to horizontal (the Music app shows album covers). And I can't quite seem to get it working. So far I've tried variations of the following:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
TMFHorizontalFavoritesViewController *horizontalVC = [[TMFHorizontalFavoritesViewController alloc] init];
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation)) {
[self presentViewController:horizontalVC animated:YES completion:nil];
}
}
But at best all I seem to get is a black screen. I've tried googling and searching here on Stackoverflow for similar questions, but I can't seem to piece together the right answer. If anyone has any input it would be much appreciated!
If there's one piece of advise I could give new iOS programmers, it would be never ever instantiate a view controller with alloc init (there are times when it's legit, but newbies almost always get it wrong).
This is how you do it with a storyboard defined controller,
TMFHorizontalFavoritesViewController *horizontalVC = [self.storyboard instantiateViewControllerWithIdentifier:#"MyIdentifier"];

uiimagepicker differentiate where the call was made

I guess this is a two part question. First part is: I have a view controller where there are two Image Views, both user inter-actable. In both I call:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
}
And the delegate method handles the picked image form the photo library. But right now I have to way of choosing which Image View gets that picture unless I make a custom UIView with two buttons where the user picks the Image View. It's more clicks and not very practical. I tried making another NSObject file but it can't use [self presentViewController...]. Calling the method in a new View Controller can't present UIImagePickerController because it's not in the window hierarchy. Is there a way to differentiate inside didFinishPickingMediaWithInfo which Image View calls the picker?
And maybe this second part of the question doesn't really belong here but it still has to do with pictures. If the user selects one picture and adds it to the gallery, goes and selects another and another...lets say 10 pictures...what's the best way of doing this, I mean GCD or NSOperationQueue? Reason why I'm asking is what if the user is on a slow mobile internet connection and after loading them to either GCD or NSOpQueue they leave the view controller...will those images continue loading to the server? I know you can make an order with NSOpQueue and I guess you can cancel the operation when the viewWillDisappear...Is that the way to do it?
I know it's a log of writing and not a lot of code but trying to learn the best way to go about all this. Thanks!
Here is my experience of what I've done in similar situations, I hope this helps.
First, regarding the initial part of your question, you have not way of reading the parameters of the method didFinishPickingMediaWithInfo to determine what UIImageView was the one pressed. But you can easily keep a reference to the lastPressedImageView in you view controller and keep it as simply as reading this variable once you receive didFinishPickingMediaWithInfo.
Regarding the second part of your question I recommend you reading / researching about AFNetworking which is a really powerful and easy to learn library for networking in iOS. You'd need to add your own logic to create the requests and send them, as well as for controlling possible errors, but this lib will help you to concentrate on logic instead of low-level networking concerns.

Changing navigation bar title in MFMailComposeViewController

It seems like I am not able to change the title on the navigation bar, which gets set to the Subject of the email (in this case "My Subject"). In this case I'd like to get rid of the title, either using an empty string as title or rendering the title invisible.
MFMailComposeViewController *mfViewController = [[MFMailComposeViewController alloc] init];
mfViewController.mailComposeDelegate = self;
[mfViewController setSubject:[NSString stringWithFormat:#"My Subject"]];
[mfViewController setMessageBody:[self emailBody] isHTML:NO];
[mfViewController setTitle:#""];
where u have presented ModalViewController
[self presentModalViewController:controller animated:YES]; // Existing line
add
[[[[controller viewControllers] lastObject] navigationItem] setTitle:#"Set the title"];
I believe this is some kind of protection came with iOS4.
It is clearly stated here that you MUST NOT change the interface provided by Apple.
http://developer.apple.com/library/ios/#documentation/MessageUI/Reference/MFMailComposeViewController_class/Reference/Reference.html
Important: The mail composition interface itself is not customizable and must not be modified by your application. In addition, after presenting the interface, your application is not allowed to make further changes to the email content. The user may still edit the content using the interface, but programmatic changes are ignored. Thus, you must set the values of content fields before presenting the interface.
i have searched the forums and some have got their app rejected, so i guess u should refrain urself from doing this.
hope it helps. happy coding :)

How do I switch to another XIB and complete release the previous XIB?

I am currently in a project creating an iPad book. Unfortunately, since this is my first iPad project I am coding in a very unconventional style.
This is a 20 page book and I have 20 XIBs. On each XIB I am calling the next XIB, but my fear is that the current XIB isn't getting unloaded and still is taking up memory. When I am about on page 10 or so, the app will crash due to didReceiveMemoryWarning.
I am switching views using 2 different methods (I don't know which one will better suit my purpose):
#METHOD 1
-(IBAction)NextPage:(id)sender
{
nextPage = [[NextPage alloc] initWithNibName:#"NextPage" bundle:nil];
[self.view addSubview:nextPage.view];
[self presentModalViewController:nextPage animated:YES];
[self.view release]; // this was added to hopefully release the current view.
}
#METHOD 2
-(IBAction)NextPage:(id)sender
{
NextPage *nextpage = [[[NextPage alloc] init] autorelease];
[self presentModalViewController:nextpage animated:YES];
}
Each view has buttons and stuff, but I want to make sure I complete erase them from memory on each page call.
I used dealloc to try to remove the view, but when I check for memory leaks and go back and forth between pages, the memory crawls up.
- (void)dealloc {
[view release]; // don't know which is which
[self.view release]; // is this correct?
[super dealloc];
}
Any help is appreciated! Thanks in advance.
If you're just switching between pages in a book, you probably shouldn't be presenting modally. Instead, you could just swap out views.
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html
... transitionFromView:toView:duration:options:completion: methods to
swap out entire sets of views for new ones.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/clm/UIView/transitionFromView:toView:duration:options:completion:
Another option would be to use layers within a view.
http://www.raywenderlich.com/2502/introduction-to-calayers-tutorial
If you present the next page modally (as you are doing), the current page won't be released. Instead, set your window's rootViewController to the new page.
UINavigationController could handle this much more simply. Take a look at the documentation. Also, as of iOS5 there is now a book type viewController that may serve you well.

Resources