Issue with portrait display after playing landscape video - xcode

I have an iPhone app that displays files to the user (videos, pdf files and documents). When you click on a file thumbnail in my FileViewController I call UIDocumentInteractionController to present the file to the user. All app screens are locked to portrait orientation apart from the document controller, that can be rotated to view landscape. This has all worked fine in previous releases, but it has suddenly changed and broken, I presume when iOS 8 was released.
Now, if I play a video and rotate it to landscape and hit done, the video is removed from the screen and the FileViewController nib that called the document the view is cut off half way down the screen.
I've done some testing and have printed out the view bounds width and height. Testing on an iPhone 4S, when I first load the FileViewController the width and height is 320 x 480, correct.
When I play a video in landscape mode and hit done, the underlaying view is automatically rotated back to portrait as landscape isn't support in this view, but when printing out the screen bounds the width is 480 and height 320. It still thinks the app is in landscape even though it's been moved back to portrait. The screen itself is the right way round, just cut off after 320 pixels!
I've been trying to manipulate the orientation of alsorts of controls but I can't see what's even generating the issue, let alone fixing it.
This is how I have implemented by orientations:
The App has been set up to support ALL orientations.
I have subclasses the tab bar controller to specify the following:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
Within FileViewController I call the following code:
- (void) Show_File:(File *)file
{
NSURL *targetURL = [NSURL fileURLWithPath:filePath];
UIDocumentInteractionController *document = [UIDocumentInteractionController interactionControllerWithURL: targetURL];
document.delegate = self;
[document presentPreviewAnimated: YES];
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
{
AppDelegate *theDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
return theDelegate.fileNavController.childViewControllerForStatusBarHidden;
}
Any ideas? I've search around but I can't find anyone having this particular issue. Thanks.

Just for anyone else experiencing this issue, I raised a support ticket with Apple and apparently it is an iOS bug....
"This is a bug QLPreviewController (which is used by UIDocumentInteractionController to display previews)"
I have a work around which is working ok for now. In my subclass of UITabBarController I've incldued this code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.transitionCoordinator && self.presentedViewController.presentationController {
self.view.frame = self.presentedViewController.presentationController.containerView.bounds;
}
}

Related

Different UINavigationBar height on iOS8

I'm running two separate apps on iOS8. In the screen shot below you can see that the UINavigationBar on the left has a height greater then the one on the right. What could be the cause of this?
Set the toolbar delegate. Then in your view controller, implement UIBarPositioningDelegate. Implement it as follows:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
return UIBarPositionTopAttached;
}
and
self.navigationController.navigationBar.translucent = NO; in viewDidLoad

Can UIPopoverPresentationController be forced to reposition popover instead of resizing it?

I am using auto layout with Storyboard. I present a popoverPresentationController from a cell rect:
NumberController * viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"NumberController"];
UIPopoverPresentationController *pc = [viewController popoverPresentationController];
pc.delegate = self;
pc.permittedArrowDirections = UIPopoverArrowDirectionAny;
pc.sourceView = tableView;
pc.sourceRect = [tableView rectForRowAtIndexPath:indexPath];
[self.navigationController presentViewController:viewController animated:animated completion:nil];
The popover presents on an iPad in portrait mode with the arrow up.
I rotate the iPad to landscape mode. The popoverPresentationController keeps the same sourceView/sourceRect and properly points to the cell. It also keeps the up arrow.
But it is now at the bottom of the view, so the popover resizes to a shorter height. This is not desired behavior.
If the popover were simply to move to a new position and change the arrow direction, it would not need to resize at all. This is the desired behavior.
I thought the following method might permit me to make changes, but it is not called since the sourceView rect does not change:
- (void)popoverController:(UIPopoverController *)popoverController
willRepositionPopoverToRect:(inout CGRect *)rect
inView:(inout UIView **)view {
}
I have tried to reset the permittedArrowDirections (in preferredContentSize, because this seemed like the most logical place). This does not work (the popover still resizes):
- (CGSize) preferredContentSize {
[super preferredContentSize];
self.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionUnknown;
return CGSizeMake(DEFAULT_POPOVER_WIDTH,DEFAULT_POPOVER_HEIGHT);
}
I simply cannot find a way to force the popoverPresentationController to change arrow direction and reposition the popover instead of resizing the popover. I am beginning to think it is not even possible - but I still hold out hope that I am just missing something.
EDIT: In the meantime, it has occurred to me that maybe a popover is not the best way to present this view if I don't want it resized in iPad. I am going to try it with UIModalPresentationFormSheet presentation. But I would still like to find an answer to this question.
I just ran into the problem where
- (void)popoverController:(UIPopoverController *)popoverController
willRepositionPopoverToRect:(inout CGRect *)rect
inView:(inout UIView **)view {
was not being called because my view controller was detached. There may be a view in your view hierarchy whose view controller has not been added as a child view controller.
I thought the following method might permit me to make changes, but it is not called since the sourceView rect does not change
The sourceView rect does not have to change, just the interface orientation. From the UIPopoverControllerDelegate documentation:
For popovers that were presented using the presentPopoverFromRect:inView:permittedArrowDirections:animated: method, the popover controller calls this method when the interface orientation changes.

Pinch Zoom into UIImageView inside a UITableViewCell

I am creating a tableview where I will have an UIImageViewinside a UITableViewCell that I would like to allow the user to zoom into. I have been able to create this effect inside a UIScrollView but have struggled to get it right for zooming into a single UITableViewCell.
At the bottom I have included the code that has worked for me for the UIScrollView. The challenge starts with what to return for the viewForZoomingInScrollView. If I try to give this method the UIImageView from the cell It throws an errors as it appears the viewForZoomingInScrollView is called before the table is loaded thus it can not find the cell I am referencing. If I pass the entire view itself self.view I can scroll but the entire tableview is zoomed (where I would like to zoom just the UIImageView inside the cell) and when I release the zoom I get an error Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan nan; 375 667] which is clearly not the correct path to take.
Any help or guidance here would be appreciated.
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
[self centerScrollViewContents];
}
- (void)centerScrollViewContents {
CGSize boundsSize = zoomTable.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
It sounds to me as though you want something like what Facebook or Twitter have, where you tap on an image and it zooms to fit the screen.
What you need to do is to consider that as a navigational step -- i.e. conceptually similar to what happens if you select a row in a standard table view and it pushes a new view controller onto the navigation controller stack, except that you probably want to present modally using a custom transition.
In the simple case, this would mean adding a tap gesture recogniser to the cell's image view; for the full effect you would add a pinch gesture recogniser to make an interactive transition.
I'd recommend watching the following WWDC videos:
2013 Session 218 "Custom Transitions Using View Controllers"
2014 Session 214 "View Controller Advancements in iOS 8"
2014 Session 228 "A Look Inside Presentation Controllers"
From your question What I understand is that you wanted to implement the functionality of Zoom in and Zoom out for ImageView. You first implemented that in a sample where you had a ScrollView Inside a ViewController and then ImageView inside that ScrollView. Things worked for you as expected. But then when you wanted the same functionality inside the TableViewCell, things didn't work for you.
So, I am suggesting you to use a View inside ScrollView as a ZoomView, and that ZoomView should have the ImageView as subview. And return that ZoomView in the method:
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.ZoomView; }

Status Bar returns when UIImagePickerViewController is called?

Everything in my app is working a treat - but there is one niggling problem.
The UIImagePickerController seems to return the status bar when it is called. Obviously the app has the statusbar hidden throughout.
Now I have worked around this by rehiding it upon completion or canelation of the picker. This resulted in a black bar at the top of the app. So after the rehide I have had to reposition the titlebar and other table contents for it to fit.
All in all this works perfectly fine. However, the UIImagePickerController is called in detail view of a table. Therefore when the user has used the picker (and ive resized after use) and clicks the back button to return to the main table there is a small graphical glitch.
The detail view has been shifted up to hide the statusbar void, yet when I return to the main table and the app slides horizontally back to the main view, for a split second a 20px black box can be seen above the items on the detail view?
To recap. UIImagePickerController returns the staus bar (seemingly no matter what) and after coding to get rid and reformat the view I get a time (messy) graphical issue when returning to the main view.
Surely there is a way to stop the statusbar returning so I dont have to bodge bar back out using code? I have it set 'off' in the plist.
It very odd! Cheers
This helps to me.
1) You must delegate the UIImagePickerController
2) Add this to ViewController:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{ // Esconder el StatusBar. Provocado por el iOS7 y el UIImagePickerController
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
}
implementing UIimagepicker controller use this.and hide status bar in to plist(statusbar initialy hidden=true) and set Uiview size 320x480 & implementing this
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *picker= [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}

Xcode 4.2.1 UIScrollViews not scrolling in storyboard

So basically I have this project, where I have 4 different tab bar pages. 2 of them uses navigation controller & tab bar, and 2 are just view controllers. Now there is this one viewcontroller, which I need to add a scroll view to. So basically, I click on the item in the tab bar, it takes me to a view controller, where I can scroll down and up. I have been following Youtube Video Link, but I do not get it to work. The problem is that I use the exact code, and I change the ViewController class to the .h and .m name (ScrollViewViewController), and I put in a scroll view that has 320 x 1000, and a button at the top, but it doesn't scroll! How can I solve this problem?
Note: That if you don't know my problem, but could very detailed walk me through on how to add a scroll view to storyboards in xcode 4.2, then that would be amazing :)!
scrollerViewController.m:
- (void)viewDidLoad {
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(320, 1000)];
[super viewDidLoad];
}
scrollerViewController.h
#interface scrollerViewController : UIViewController {
IBOutlet UIScrollView *scroller;
}
#end
And here comes a picture of the storyboard.
I need some of the code in order to really know your problem, but let me throw in my guess. You may be setting the size 320x1000 to the frame size of the scrollview by any chance? The frame size of the scrollview has to stay 320x480, and the contentSize should be 320x1000. Sorry if it was a wrong guess, but shouldn't do any harm :)
Something like this in your ViewController of the scrollView...
- (void) viewDidLoad {
[super viewDidLoad];
UIScrollView * scrollView = self.view;
scrollView.frame = (CGRect){scrollView.frame.origin, CGSizeMake(320, 480)};
scrollView.contentSize = CGSizeMake(320, 1000);
scrollView.backgroundColor = [UIColor whiteColor]; // I am setting the white background, so that the scroll indicator is visible
}
I am assuming you are setting ScrollView as the top view of the ViewController in your Storyboard as in the attached image.
I followed the exact same movie and it did not work for me either. But this movie did: http://www.youtube.com/watch?v=YBlwepYK7Zs
I followed that one and now i got it to work.
A bit late but might be more people looking for a solution to this.

Resources