UIPopoverController not sizing correctly in iOS 8 - objective-c

Prior to iOS 8 my app using UIPopoverController was working fine. I had it anchored and opening up at a size of 400 x 215. However now when i run my app on iPad using iOS 8 my popover window is not sized properly. Its almost popping up at the full height and width off my anchor. Since iOS is so new i can't seem to find an adjustment for this. Below is my code:
UIView *anchor = self.personAnchor;
UIViewController *viewControllerForPopover =
[self.storyboard instantiateViewControllerWithIdentifier:#"choosePersonViewController"];
popover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
popover.popoverContentSize = CGSizeMake(400, 215);
popover.delegate = self;
[popover presentPopoverFromRect:anchor.frame
inView:anchor.superview
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Set the view controller's preferredContentSize instead of setting the popover's popoverContentSize - copied from comment

Related

SafeArea in iOS 11: how add view on main screen with custom navigationBar without safeArea from code in objective-c

In my project on Objective-C mainScreen with Custom NavigationBar (created from code):
mainNavigationController = [[NavigationController alloc] initWithRootViewController:mainMenuViewController];
mainNavigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
mainNavigationController.delegate = self;
mainNavigationController.navigationBar.tintColor = [UIColor whiteColor];
UIWindow* window = self.window;
window.backgroundColor = [UIColor whiteColor];
window.rootViewController = mainNavigationController;
[window makeKeyAndVisible];
I change self.view like size [UIScreen mainScreen].applicationFrame]:
UIView* mainView = [[[MainViewControllerView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
self.view = mainView;
In mainScreenView I add scrollView:
scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
scrollView.autoresizesSubviews = YES;
scrollView.autoresizingMask = UIViewAutoresizingNone;
scrollView.backgroundColor = [UIColor clearColor];
scrollView.bounces = NO;
And add some subView inside scrollView:
[scrollView addSubview:myLogoView];
[scrollView addSubview:littleScrollView];
[scrollView addSubview:firstButton];
[scrollView addSubview:secondButton];
[scrollView addSubview:thirdButton];
[scrollView addSubview:fouthButton];
[scrollView addSubview:fifthButton];
[scrollView addSubview:sixthButton];
[scrollView addSubview:seventhButton];
[scrollView addSubview:activityIndicatorView];
https://www.dropbox.com/s/ttrkolgnch80kr9/safeArea.png?dl=0
If use XCODE 8 and iOS <= 10, all view place correct on mainScreen (myLogoView place ignore size of custom NavigationBar and have coordinate Y == 20.0 in absolute value coordinates of device screen),
but if use XCode 9 and iOS 11 myLogoView have place under my custom navigationBar (height == 44) myLogoView Y == 64.0 in absolute value coordinates of device screen, in iOS 10 (under xCode9) all working good - added view on mainScreen placed in start coordinates of screen and ignore height of custom NavigationBar.
In swift and storyboard I know how it fixed in iOS11 easy remove safeArea top line, but how remove safeArea from code in Objective-C.
How fix this trouble?
Safe area in iOS 11 is replacement of top & bottom layout and apple provide more detail on this like below :
The layout guide representing the portion of your view that is
unobscured by bars and other content. In iOS 11, Apple is deprecating
the top and bottom layout guides and replacing them with a single safe
area layout guide.
So base on this now top & bottom layout replaced with single safe area but agin if you are not using default NavigationBar so you can disable safe area in storyboard like below :
You can Uncheck safe area and it will revert to top & bottom layout.
Ref Before & After uncheck safe area:
Before or default :
Uncheck Safe area or old behavior :
Hope this will help to understand new iOS 11 update related to top & bottom layout and change your code as per this layout change.
Also here is one good blog to explain more on Safe area layout : Safe area

Prevent shutter animation from appearing full screen when using cameraOverlayView [duplicate]

I have a transparent view with a rectangle drawn onto it using CoreGraphics.
When the camera launches the custom overlay view is above the shutter animation.
What you see is the standard camera shutter with the custom rectangle above it.
How do I get it to go in the right place, underneath the shutter animation? I've looked at other sample code but it's for OS 3.1 and doesn't seem to do anything differently.
Here's my code:
-(IBAction)cameraButton{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerCameraDeviceRear]){
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//Add the OverlayView with the custom Rectangle
CGRect overlayFrame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
OverlayView *overlayView = [[OverlayView alloc]initWithFrame:overlayFrame];
picker.cameraOverlayView = overlayView;
[overlayView release];
[self presentModalViewController:picker animated:YES];
[picker release];
}
}
On the iPad this problem doesn't exist, and the overlay view is behind the shutter animation by default. But on the iPhone, the overlay appears at front.
I've found a solution that worked for me.
You have to set your overlay view as a subview in this method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (!viewController)
return;
UIView* controllerViewHolder = viewController.view;
UIView* controllerCameraView = [[controllerViewHolder subviews] objectAtIndex:0];
UIView* controllerPreview = [[controllerCameraView subviews] objectAtIndex:0];
[controllerCameraView insertSubview:self.overlayView aboveSubview:controllerPreview];
}
Hope it helps
Original source:
http://www.alexcurylo.com/blog/2009/06/18/uiimagepickercontroller-in-3-0/
You may not do anything else other than what you're already doing; if iOS decides to put your overlay view over the shutter, you'll just have to live with it (unless you want to risk getting rejected from the app store).
As an imperfect workaround, you could start your overlay with alpha=0 and then set alpha to 1 a second or two later. But there is no set time period that the shutter appears for before 'opening' (I think it depends on how long it takes to initialize the camera hardware), so sometimes your interface might not appear until late and sometimes might appear too early.
As of 4.3.3, the shutter animation is broken because elements are displayed on top, and then snap underneath when the animation starts. I've filed this as a Radar: http://openradar.appspot.com/radar?id=1204401
I answered a similar question here. What worked for me (in iOS 6) was setting the cameraOverlayView in navigationController:willShowViewController:animated.
- (void) navigationController:(UINavigationController*) navigationController willShowViewController:(UIViewController*) viewController animated:(BOOL) animated {
self.imagePickerController.cameraOverlayView = ...; // your camera overlay view
}

Setting a view using inset of bounds

I started up an Xcode project using the 'single view' application template and added two lines to the template-created ViewController class in viewDidLoad:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectInset(self.view.bounds, 10, 10)];
[self.view addSubview:textView];
When I run this in the 3.5 inch iPhone simulator, the textview extends off the bottom of the screen. I intended for it to be placed in the center of the screen with a 10 point border.
Am I missing something basic? It seems to work fine in the 4" simulator. Is it a simulator bug?
It's not a bug in the simulator.
The Xcode template includes a xib, and in that xib is the view controller's top-level view (self.view), and that view is sized for the iPhone 5 screen.
When the system sends viewDidLoad to your view controller, it hasn't yet resized that view for the screen size of the current device. So your text view's frame is based on the size of an iPhone 5 screen.
You can fix this by setting the autoresizing flags on your view:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectInset(self.view.bounds, 10, 10)];
[self.view addSubview:textView];
textView.autoresizingMask = UIViewAutoresizingFlexibleHeight
| UIViewAutoresizingFlexibleWidth;
Your xib is set up to use autolayout by default, so you can also have the system resize your text view by setting constraints between your text view and your top-level view:
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectInset(self.view.bounds, 10, 10)];
[self.view addSubview:textView];
textView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"H:|-10-[textView]-10-|" options:0 metrics:nil
views:NSDictionaryOfVariableBindings(textView)]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"V:|-10-[textView]-10-|" options:0 metrics:nil
views:NSDictionaryOfVariableBindings(textView)]];
If you put your text view in the xib instead of creating it in code, you can use the xib editor (aka “Interface Builder” or “IB”) to set up the constraints. I highly recommend watching the autolayout videos from WWDC 2012:
Session 202 - Introduction to Auto Layout for iOS and OS X
Session 228 - Best Practices for Mastering Auto Layout
Session 232 - Auto Layout by Example

Camera Shutter shows up in front of custom UIView?

I have a custom UIView that I have created to display my custom buttons and toolBar. When I first called for it to show, the bar is on top of the Shutter (which is good). But after the camera is loaded, the shutter comes in front of it, then opens.
If you look at the native camera.app, it doesn't do this. The toolbar stays there the whole time. Here is my code:
// .h
UIImagePickerController *theCamera;
#property (nonatomic, retain) UIImagePickerController *theCamera;
// .m
theCamera = [[UIImagePickerController alloc] init];
theCamera.delegate = self;
theCamera.sourceType = UIImagePickerControllerSourceTypeCamera;
theCamera.showsCameraControls = NO;
theCamera.toolbar.alpha = 0;
theCamera.navigationBarHidden = YES;
theCamera.toolbarHidden = YES;
theCamera.wantsFullScreenLayout = YES;
theCamera.cameraViewTransform = CGAffineTransformMakeScale(1.25, 1.25);
UIImageView *tabBarBack = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tab_bar_back.png"]];
tabBarBack.frame = CGRectMake(0, 422, 320, 58);
[customView addSubview:tabBarBack];
theCamera.cameraOverlayView = customView;
[self presentModalViewController:theCamera animated:YES];
Obviously there are more buttons I add to the customView, but you get the concept.
Subscribe to:
AVCaptureSessionDidStartRunningNotification
This is when the iris open animation begins. If you add a cameraOverlayView during this time, it will be properly covered up by the iris. It is posted at the same time as that PL… private notification. This is a documented approach that does not risk app rejection.
AFAIK there is no direct way to do this. If you use cameraOverlay, you will get shutter for the complete screen.
How ever there are some alternate methods (playing around with the view hierarchy) that will help you in making your preview screen as parent view. I am not sure if this approach is correct as per app store guidelines.
have a look at Hide/Show iPhone Camera Iris/Shutter animation for better understanding on how to achieve this.
On iOS 6+, if you've added your controller as the delegate for the UIImagePickerController, this code should ensure that the shutter stays behind your cameraOverlayView:
- (void) navigationController:(UINavigationController*) navigationController willShowViewController:(UIViewController*) viewController animated:(BOOL) animated {
self.imagePickerController.cameraOverlayView = ...; // your camera overlay view
}
I haven't tested on versions of iOS prior to iOS 6 though.

MPMoviePlayerViewController customization

I'm using MPMoviePlayerViewController - with the player controls set to: MPMovieControlStyleFullscreen
I'm having a problem with some of buttons that are in MPMovieControlStyleFullscreen: forward, reverse, and fullscreen (the one with the arrows pointing at eachother).
I would like to either remove the forward, reverse, and fullscreen buttons or control what they do when the user taps them.
Thank you!
There isn't a way to customize the MPMovieControlStyle values provided by Apple. What you need to do is is turn off the Apple controls (MPMovieControlStyleNone) and then create your own custom controls. Apple is fine with you putting your own UIViews in to the hierarchy here, so you can get started with something like this:
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: YOUR_URL];
moviePlayer.controlStyle = MPMovieControlStyleNone;
UIView *movieView = moviePlayer.view;
[movieView addSubview: _movieControlsView];
[movieView bringSubviewToFront: _movieControlsView];
Where _movieControlsView was set up earlier in code or in IB.
Aesthetically, you can do what you want, but I would recommend sticking with something that looks like Apple's choices so as not to confuse the user. For the project I just finished, I created a transparent button the exact size of the movie player. Clicking the button fades in a control bar on the bottom with my custom controls. If one of the controls isn't clicked, the control bar fades back out again after a few seconds.
First off, MPMoviePlayerController is a little different than MPMoviePlayer*View*Controller, so some of these answers lead to problems when converting applications that were built in an iOS 4.3+ environment.
I've built some apps using MPMoviePlayerController that worked fine when built in iOS 3.2. When I rebuilt it with XCode 3.2.6, (iOS 4.3), the videos don't even play on the iPhone. I since fixed that by adding the MPMoviePlayerController instance to a subView, then presenting a modal (Player is a UIViewController) with the movplayer in fullScreenMode:
//from didSelectRowAtIndexPath
Vid *selected = [items objectAtIndex:position];
player = [[Player alloc] init];
movplayer = [[MPMoviePlayerController alloc] initWithContentURL:selected.vidURL];
movplayer.view.frame = player.view.bounds;
movplayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
[player.view addSubview:movplayer.view];
[self presentModalViewController:player animated:YES];
[movplayer setFullscreen:YES animated:NO];
[movplayer play];
[player release];
//movplayer is released inside - (void)exitedFullscreen:(NSNotification*)notification
This was done on account of the UINavigationBar being half cut off when rotating.
When I got to the iPad version of the app the modal option wouldn't work aesthetically. It was also having the UISplitViewController navBar and toolbars half cut off when rotating in full screen mode. So I tried implementing MPMoviePlayerViewController instead of MPMoviePlayerController. With this conversion, XCode gave me errors when trying to set:
movplayer.controlStyle = MPMovieControlStyleEmbedded;
The proper way to do this with a MPMoviePlayerViewController is:
movplayer.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
When the player is added as a subView, the pinch gestures will toggle the player between fullScreen and the size of your parentView (player.view.bounds) smoothly, as well as preserve the toolbars and navBars native to the parent.
//iPad version with a view (viewForMovie) inside the DetailViewController
movplayer = [[MPMoviePlayerViewController alloc] initWithContentURL:[current vidURL]];
movplayer.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
movplayer.view.backgroundColor = [UIColor clearColor];
movplayer.view.frame = viewForMovie.bounds;
[viewForMovie addSubview:movplayer.view];
So these two examples show some workarounds for those who want to convert their iPhone or iPad apps to a newer iOS version.
Try setting MPMovieControlStyle of your MPMoviePlayerController object to MPMovieControlStyleNone