Black Bar in UIImagePicker on iPad - Only in Landscape Right Orientation - objective-c

I am showing a UIImagePicker (itself in a UIView) via a UIPopOver. This works fine, however when the iPad is rotated onto its right side I get a strange black bar along the left hand side of the popover as per the image below. The cancel button is also partially off the right hand of the screen. This doesn't happen in any other orientation which is odd.
The code is also listed below. Can anyone suggest why I am getting this black bar ?
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
UIViewController *containerController = [[UIViewController alloc] init];
containerController.contentSizeForViewInPopover = CGSizeMake(width, height);
[imagePickerController.view setFrame:containerController.view.frame];
[containerController.view addSubview:imagePickerController.view];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Class cls = NSClassFromString(#"UIPopoverController");
if (cls != nil) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:containerController];
[popoverController presentPopoverFromRect:selectedRect inView:self.view permittedArrowDirections:4 animated:YES];
[containerController release];
}

For some strange reason, the view's frame does change in landscape right.
To come over this, set the frame after you present the popover (view code below).
That should do the trick.
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
UIViewController *containerController = [[UIViewController alloc] init];
containerController.contentSizeForViewInPopover = CGSizeMake(width, height);
[containerController.view addSubview:imagePickerController.view];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Class cls = NSClassFromString(#"UIPopoverController");
if (cls != nil) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:containerController];
[popoverController presentPopoverFromRect:selectedRect inView:self.view permittedArrowDirections:4 animated:YES];
[imagePickerController.view setFrame:containerController.view.frame];
[containerController release];
}
Also, in your controller, add this to reset the frames when the rotation occurs:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[imagePickerController.view setFrame:imagePickerController.view.superview.frame];
}

The above approach works with iOS 5 and above but on iOS 4 and prior it's not possible to add the UIImagePickerController as a subview and then show it. It always has to be presented as a ModalViewController.

Try this. Reposting one solution I found using [currentDevice endGeneratingDeviceOrientationNotifications]
UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.delegate = self;
// Display the camera.
[self presentModalViewController:picker animated:YES];
// Given by default your orientation is in landscape right already
while ([currentDevice isGeneratingDeviceOrientationNotifications])
[currentDevice endGeneratingDeviceOrientationNotifications];
Source: Disable rotation in UIImagePicker

Related

iOS 8 UIActivityViewController and/or UIPopoverController are not dissmissed when clicked outside of them

I have read the UIPopoverController docs and more then 10 stackoverflow solutions which none work in iOS 8.0.2 ipad device.
THE GOAL:
I want to present a sharing view which when clicked outside dissmisses.
THE PROBLEM:
The code works fine below iOS 8.0.
THE CODE (tried many versions...):
NSArray *dataToShare = #[url]; // ...or whatever pieces of data you want to share.
UIActivityViewController* activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:dataToShare
applicationActivities:nil];
activityViewController.modalInPopover = YES;
self.act = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
[self.act presentPopoverFromRect:CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, self.view.bounds.size.width/2, self.view.bounds.size.width/2) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
self.act.delegate = self;
I have added the :
UIPopoverControllerDelegate
WHAT I HAVE TRIED:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
As soon that the
UIPopoverController
is presented the view losses focus and doesn't register touches. Therefore, I can't handle touches outside the self.act rect space in order to force a dissmisal.
also...
NSArray *dataToShare = #[url]; // ...or whatever pieces of data you want to share.
UIActivityViewController* activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:dataToShare
applicationActivities:nil];
activityViewController.modalInPopover = YES;
UIPopoverPresentationController *presentationController = [activityViewController popoverPresentationController];
presentationController.sourceView = self.view; // if button or change to self.view.
[self.parentViewController presentViewController:activityViewController animated:YES completion:nil];
and I tried to present the UIActivityViewController and UIPopoverController from the parent which didn't work aswell.
Please help, I lost half day on something this stupid which works on iOS 7.1 and not on iOS 8+ which is ridiculous and I still have no clue why.
I will try to add the cancel button which has also disappeared in iOS8+.
UPDATE 1:
Adding a UIButton inside a UIBarButtonItem didn't help...
UIButton *control = (UIButton *) sender;
[control setFrame:CGRectMake(300, 300, 100, 100)];
[control setBackgroundColor:[UIColor redColor]];
UIBarButtonItem *barButtonItemView = [[UIBarButtonItem alloc] init];
[barButtonItemView setCustomView:control];
[self.popup presentPopoverFromBarButtonItem:barButtonItemView permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
UPDATE 2 - 19.12.2014. (iOS 7.1. - 8.1.2):
The accepted answer works on iOS 8.1. I had some errors with iOS 7.1. so I modified it to work for iOS 7.1. I have stated on which devices the code works in the comments below the answer.
// publish - sharing
NSArray *dataToShare = #[url]; // ...or whatever pieces of data you want to share.
UIActivityViewController* activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:dataToShare
applicationActivities:nil];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSLog(#" SHARING - 1 - ");
[self presentViewController:activityViewController animated:YES completion:^{}];
}
else
{
// Change Rect to position Popover
NSLog(#" SHARING - 2 - ");
self.popup = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
[self.popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width * 3 / 5 ,
self.view.frame.size.width/2,
self.view.frame.size.width/10,
self.view.frame.size.width/10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
How about just add this.
UIActivityViewController* activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:dataToShare
applicationActivities:nil];
activityViewController.modalInPopover = YES;
activityViewController.popoverPresentationController.sourceView = self.view;

Shift to UIPopoverPresentationController

I want to create the same popover for my iPhone app with size GGrect of (320 100.0).
Here is my old code:
View * pk1 = [[View alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:pk1];
pop = [[UIPopoverController alloc] initWithContentViewController:nav];
[pop setDelegate:self];
[pop presentPopoverFromRect:[self btnsavepart].frame inView:[self view] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[nav release];
I using this codes but its doesn't change
nav.preferredContentSize = CGSizeMake(320, 100);
I can not change UIpopovercontriller with UIPopoverPresentationController.
How do I specify GGrect of (320 100.0)?
i thinks i can change only on horizontally but how can i do.
View *viewController = [[[View alloc] init] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
navController.modalPresentationStyle = UIModalPresentationPopover;
navController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
navController.popoverPresentationController.sourceRect = btnsavepart.bounds;
navController.popoverPresentationController.sourceView = btnsavepart;
navController.popoverPresentationController.delegate = self;
[self presentViewController:navController animated:YES completion:nil];
i want the UIPopoverPresentationController not FullScreen form in iPhone
i adding this codes but i give the FullScreen view
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return NO;
}
I work with Xamarin but its same thing , to specify size of the popover in which you want to display your UIViewController, in the properties of your UIVIewController you have the PreferredContentSize property. There you specify the size.
I saw it somewhere here but forgot where.

UiSearchBar OffScreen when Initialised - iPad

I have the following code which works under iOS5 for putting a UISearchBar at the top of a UITableView on the iPad :
- (void)viewDidLoad
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CGRect searchViewFrame = CGRectMake(33, 33, 264, 45);
UIView *containerSearch = [[UIView alloc] initWithFrame: searchViewFrame];
searchBar = [[UISearchBar alloc] init];
searchBar.barStyle = UIBarStyleDefault;
[containerSearch addSubview: searchBar];
self.tableView.tableHeaderView = containerSearch;
searchController = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar
contentsController:self];
searchBar.delegate = self;
searchController.delegate = self;
searchController.searchResultsDelegate=self;
searchController.searchResultsDataSource=self;
[searchBar release];
}
Under iOS6 however this code behaves strangely. When the iPad is started in landscape mode the UISearchBar is offscreen. It does not appear in its correct position until the ipad is rotated to portrait and back to landscape.
Is this just an iOS6 bug or any suggestions as to how it can be fixed ?
Thanks !
Have you tried to init the searchbar with a frame? searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,265,45)];

Changing size of UIImagePicker presented via UIPopOver (iPad)

I am trying to change the size of a UIImagePicker which I am presenting via a UIPopOver. The code is shown below. The issue is that the PopOver size doesn't display properly - it briefly flashes up in the correct size, then animates down to the usual default size.
Can anybody advise me on how I can change the size of the popover ?
- (void)showImagePickerForPhotoLibrary {
NSLog(#"Picker");
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.contentSizeForViewInPopover = CGSizeMake(768, 1000);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Class cls = NSClassFromString(#"UIPopoverController");
if (cls != nil) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];
//popoverController.popoverContentSize = CGSizeMake(768, 1000);
[popoverController presentPopoverFromRect:selectedRect inView:self.view permittedArrowDirections:4 animated:YES];
}
}
else {
[app.mainViewController presentModalViewController:imagePickerController animated:YES];
}
}
I'm not sure this is the most elegant solution, however it seems to work fine for me:
You can embed the UIImagePickerController's view into a "container" UIViewController's view.
- (void)showImagePickerForPhotoLibrary {
NSLog(#"Picker");
imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
UIViewController *containerController = [[UIViewController alloc] init];
containerController.contentSizeForViewInPopover = CGSizeMake(768, 1000);
[containerController.view addSubview:imagePickerController.view];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Class cls = NSClassFromString(#"UIPopoverController");
if (cls != nil) {
popoverController = [[UIPopoverController alloc] initWithContentViewController:containerController];
[popoverController presentPopoverFromRect:selectedRect inView:self.view permittedArrowDirections:4 animated:YES];
[imagePickerController.view setFrame:containerController.view.frame];
}
}
else {
[app.mainViewController presentModalViewController:containerController animated:YES];
}
}
Hope this helps
EDIT: for some strange reason, the frame does indeed change when in landscape right.
To come over this, you need to set the image picker's view's frame after you present the popover.
I have edited the code above to show this.
Also, in your controller, add this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[imagePickerController.view setFrame:imagePickerController.view.superview.frame];
}
When I tried Mutix's solution the popover showed just the navigation bar with an empty white view.
My way around it was to add imagePickerController as a child of containerController and not just adding the picker's view.
Mainly it means to replace this line:
[containerController.view addSubview:imagePickerController.view];
with these lines:
[containerController addChildViewController:imagePickerController];
[containerController.view addSubview:imagePickerController.view];
[imagePickerController didMoveToParentViewController:containerController];
In addition, when using this approach, I didn't need any special handling for landscape mode.

How do I make UISearchBar in a UINavigationBar resize only the left margin using a block animation?

I am trying to duplicate the UISearchBar animation seen in mobile Safari. Instead of only moving the left margin, the UISearchBar Expands off the screen and then "jumps" into the proper location. The downsizing is similarly uneven. How can I make this animation even like the UISearchBar in mobile safari?
searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0,0,175,44)] autorelease];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
searchBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;
UIBarButtonItem *customBarItemRight = [[[UIBarButtonItem alloc] initWithCustomView:searchBar] autorelease];
tabBarController.navigationItem.rightBarButtonItem = customBarItemRight;
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
searchDisplayController.searchResultsTableView.hidden = NO;
[UIView animateWithDuration:.3
animations:^ {
CGRect newBounds = searchBar.bounds;
newBounds.size.width = 350;
searchBar.bounds = newBounds;
}];
[searchDisplayController setActive:YES animated:YES];
}
You should not use UISearchDisplayController for this, you need to implement animation for your custom view controller.