Reputation: 5820
The view system in my app is highly customized and uses a number of views that are manually rotated from portrait to landscape based on user interactions (the rotation is done by applying an affine transform to the view/layer).
I want to present a popover inside one of these rotated views, but the orientation of the popover always appears relative to the orientation of the device (i.e., not relative to the view). I'm guessing the answer is no, but just in case someone has a clever idea: is there any way to manually rotate the view that is presented by UIPopoverController?
Upvotes: 1
Views: 1031
Reputation: 162
Are you trying to rotate the popover or just the content shown in the popover? You can control some of the former by setting which arrow orientations are possible. I'm interested in the latter, and it seems to work just by grabbing the content view controller. E.g.:
aPopoverController.contentViewController.view.transform = CGAffineTransformMakeRotation(M_PI);
Upvotes: 1
Reputation: 5820
DISCLAIMER: If you're at all interested in trying to get your app into the store, this code is almost certainly grounds for rejection. It dives into UIKit's private API's which is a big no-no as far as apple is concerned.
@RunningPink had the right idea. Depending on how the view hierarchy is set up, the popover may be back up farther than two superviews. The popover itself it an instance of the (private) class _UIPopover
(at least in iOS 5). You can find this view by doing:
UIView *possiblePopover = popoverController.contentViewController.view;
while (possiblePopover != nil) {
// Climb up the view hierarchy
possiblePopover = possiblePopover.superview;
if ( [NSStringFromClass([possiblePopover class]) isEqualToString:@"_UIPopoverView"] ) {
// We found the popover, break out of the loop
break;
}
}
if (nil != possiblePopover) {
// Do whatever you want with the popover
}
In doing this, I found that transforming the view often ended up making the popover look blurry. I found the reason was that the popover's superview was an instance of another private class called UIDimmingView
which is responsible for accepting touches outside of the popover and causing the popover to dismiss. Performing the rotation on the dimming view removed the blurriness I was seeing in the popover.
However, transforming the dimming can result in weirdness where certain parts of the window are not "covered" by the dimming view so the popover will not dismiss if these parts of the window are tapped. To get around this, I applied the rotation to the dimming view, reset the dimming view's frame to cover the screen, and then translated the popover view into place.
if (nil != possiblePopover) {
// Found the popover view
CGAffineTransform rotation = CGAffineTransformMakeRotation(-M_PI_2);
CGAffineTransform translation = // Whatever translation in necessary here
// Rotate the UIDimming View and reset its frame
[possiblePopover.superview setTransform:rotation];
[possiblePopover.superview setFrame:CGRectMake(0, 0, possiblePopover.superview.frame.size.height, possiblePopover.superview.frame.size.width)];
// Translate the popover view
[possiblePopover setTransform:translation];
}
Upvotes: 0
Reputation: 218
Sean, I just tested it for kicks, yes it works. It has to be done (in my case at least) in viewDidAppear (if done in viewWillAppear, it gets knocked back to the original setting.)
This worked just fine (just tested now) to have a popover at a 90 degree angle. i.e in my case my main view is in portrait mode and the popover is turned 90 deg.
self.navigationController.view.superview.superview.transform = CGAffineTransformMakeRotation (M_PI/2.0);
Upvotes: 1