I'm using UIPageViewController and story board in my application.
When in portrait, i'm using following code to jump from one page to another page and its working fine.
int direction = UIPageViewControllerNavigationDirectionForward;
if ([self.modelController currentPage] < pagenum)
{
direction = UIPageViewControllerNavigationDirectionForward;
}
else if ([self.modelController currentPage] > pagenum)
{
direction = UIPageViewControllerNavigationDirectionReverse;
}
[self.pageViewController setViewControllers:[NSArray arrayWithObject:[self.modelController viewControllerAtIndex:pagenum storyboard:self.storyboard]] direction:direction animated:YES completion:NULL];
But the same code is not working when we are in landscape mode. How to turn the pages when in landscape?
If you look at the Page-Based Application Template in Xcode you find the following UIPageViewControllerDelegate method:
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if (UIInterfaceOrientationIsPortrait(orientation)) {
// In portrait orientation: Set the spine position to "min" and the page view controller's view controllers array to contain just one view controller. Setting the spine position to 'UIPageViewControllerSpineLocationMid' in landscape orientation sets the doubleSided property to YES, so set it to NO here.
UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:currentViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
self.pageViewController.doubleSided = NO;
return UIPageViewControllerSpineLocationMin;
}
// In landscape orientation: Set set the spine location to "mid" and the page view controller's view controllers array to contain two view controllers. If the current page is even, set it to contain the current and next view controllers; if it is odd, set the array to contain the previous and current view controllers.
DataViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
NSArray *viewControllers = nil;
NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:currentViewController];
if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil];
} else {
UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil];
}
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
return UIPageViewControllerSpineLocationMid;
}
When returning UIPageViewControllerSpineLocationMid from the above method, you are telling the UIPageViewController that it should expect to display two UIViewControllers side by side (i.e. two pages).
The key here is that you must pass the correct number of UIViewControllers when calling the UIPageViewController's setViewControllers:direction:animated:completion: method.
Showing two pages? Pass two UIViewControllers.
Showing one page? Pass one UIViewController.
The code you presented will never pass more than one UIViewController to the UIPageViewController.
If the UIPageViewControllerSpineLocation does not correspond with the amount of UIViewControllers you are passing it will crash or just do nothing.
Let me know if you need further help.
Related
in my app i am trying to make a slider using the LWSlideShow LWSlideShow
the source of images are fetched from my server after trying the solution here i stuck with error that said unbalanced call and it means that i am presenting a modal view on a view that did not completed his animation after solving this problem by putting animation to no the splashView that i present will be dismissed before the images are downloaded here is my code for further explanation:
- (IBAction)goDownload {
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Splash"];
[self.navigationController presentViewController:vc animated:YES completion:nil];
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *array = [#[] mutableCopy];
LWSlideItem *item = [LWSlideItem itemWithCaption:#""
imageUrl:#"http://code-bee.net/geeks/images/cover-1.jpg"];
[array addObject:item];
item = [LWSlideItem itemWithCaption:#""
imageUrl:#"http://code-bee.net/geeks/images/cover-2.jpg"];
[array addObject:item];
item = [LWSlideItem itemWithCaption:#""
imageUrl:#"http://code-bee.net/geeks/images/cover-3.jpg"];
[array addObject:item];
LWSlideShow *slideShow = [[LWSlideShow alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 120)];
slideShow.autoresizingMask = UIViewAutoresizingFlexibleWidth;
//slideShow.delegate = self;
[self.view addSubview:slideShow];
slideShow.slideItems = array;
if ([slideShow.slideItems count] == [array count]) {
[self dismissViewControllerAnimated:YES completion:nil];
}
});
}
//
//-(void)viewWillAppear:(BOOL)animated
//{
//
// UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Splash"];
// [self.navigationController presentViewController:vc animated:YES completion:nil];
//}
- (void)viewDidLoad {
[super viewDidLoad];
[self goDownload];
}
also you can see from the code that also i try to use viewWillAppear same thing happened what i want is when the images are downloaded the splashView need to be dismissed i dont know what i am doing wrong
Running that code from a VC anytime before viewDidAppear (like viewDidLoad, viewWillAppear) will cause the problem you describe. But you probably don't want the slide show view to appear - even for an instant - until you're done fetching the assets. This is a common problem.
The solution is to realize that the "splash screen" and the network tasks aren't just preamble, they are as much a part of your application as the slide show.
EDIT
Make that Splash vc the app's initial view controller in storyboard. Right now, the slide show vc probably looks like this:
Uncheck the "Is Initial View Controller" checkbox, find your splash view controller (in the same storyboard, I hope) and check it's box to be the initial view controller. Now your app will start up on the splash vc, like you want it.
When the splash vc done, it can present the slide show vc, or it can even replace itself (with the slide show ) as the app window's root.
To replace the UI, I use variations of this snippet...
// in the splash vc, after all of the asset loading is complete
// give what used to be your initial view controller a storyboard id
// like #"MySlideShowUI"
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MySlideShowUI"];
UIWindow *window = [UIApplication sharedApplication].delegate.window;
window.rootViewController = vc;
[UIView transitionWithView:window
duration:0.3
options:UIViewAnimationOptionTransitionCrossDissolve
animations:nil
completion:nil];
I'm currently working on an update to one of my apps and I have come across a very strange issue to do with UITabBarController.
In my storyboard I have about 8 view controllers and in my UITabBarController subclass I add another 4 view controllers that are loaded programmatically. Most of these views need to have to UINavigationController to keep consistency when rotating as some views come out from the "More" tab into the main bar, in order to do this I have embeded them in a UINavigationController.
If you choose view 6 in portrait and the rotate the UINavigationController goes black when the view gets its own button in the tab bar, however when it returns to "more" the view comes back. In my investigation of these it seems that the UINavigationController losses the UIViewController as it root view controller.
Working as expected on a view that does not enter the "More" tab: imgur.com/gVB8wTF
Black screen if the view came from the "More" tab: http://imgur.com/WaoNoL1
I made a quick sample project that has this issue: https://github.com/joshluongo/UITabBarController-Issues
Any ideas on how to fix this?
I ran into the same issue.
I was able to come up with a workaround that works really well. I've pushed it up to Github here: https://github.com/jfahrenkrug/UITabBarControllerMoreBugWorkaround
Any improvements are welcome.
The bug happens because the stack of your UINavigationController is removed from it and put into the private UIMoreNavigationController. But upon rotating back to regular width, that stack is not correctly put back into its original UINavigationViewController.
The solution is to subclass UITabBarController and replacing its willTransitionToTraitCollection:withTransitionCoordinator: with this one:
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
//#define MORE_TAB_DEBUG 1
#ifdef MORE_TAB_DEBUG
#define MoreTabDLog(fmt, ...) NSLog((#"[More Tab Debug] " fmt), ##__VA_ARGS__);
#else
#define MoreTabDLog(...)
#endif
MoreTabDLog(#"-- before willTransitionToTraitCollection");
/*
There is a bug when going in and out of the compact size class when a tab bar
controller has more than 5 tabs. See http://www.openradar.me/25393521
It comes down to this: When you have more than 5 tabs and a view controller on a tab
beyond the 4th tab is a UINavigationController, you have a problem.
When you are on this tab in compact and push one or more VCs onto the stack and then
change back to regular width, only the top most view controller will be added back onto the
stack.
This happens because the stack of your UINavigationController is taken out of that NavVC and put
into the private UIMoreNavigationController. But upon rotating back to regular, that stack is not
correctly put back into your own NavVC.
We have 3 cases we have to handle:
1) We are on the "More" tab in compact and are looking at the UIMoreListController and then change to
regular size.
2) While in compact width, we are on a tab greater than the 4th and are changing to regular width.
3) While in regular width, we are on a tab greater than the 4th and are changing to compact width.
*/
if ((self.traitCollection.horizontalSizeClass != newCollection.horizontalSizeClass) ||
(self.traitCollection.verticalSizeClass != newCollection.verticalSizeClass))
{
/*
Case 1: We are on the "More" tab in compact and are looking at the UIMoreListController and then change to regular size.
*/
if ([self.selectedViewController isKindOfClass:[UINavigationController class]] && [NSStringFromClass([self.selectedViewController class]) hasPrefix:#"UIMore"]) {
// We are on the root of the MoreViewController in compact, going into regular.
// That means we have to pop all the viewControllers in the MoreViewController to root
#ifdef MORE_TAB_DEBUG
UINavigationController *moreNavigationController = (UINavigationController *)self.selectedViewController;
UIViewController *moreRootViewController = [moreNavigationController topViewController];
MoreTabDLog(#"-- going OUT of compact while on UIMoreList");
MoreTabDLog(#"moreRootViewController: %#", moreRootViewController);
#endif
for (NSInteger overflowVCIndex = 4; overflowVCIndex < [self.viewControllers count]; overflowVCIndex++) {
if ([self.viewControllers[overflowVCIndex] isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)self.viewControllers[overflowVCIndex];
MoreTabDLog(#"popping %# to root", navigationController);
[navigationController popToRootViewControllerAnimated:NO];
}
}
} else {
BOOL isPotentiallyInOverflow = [self.viewControllers indexOfObject:self.selectedViewController] >= 4;
MoreTabDLog(#"isPotentiallyInOverflow: %i", isPotentiallyInOverflow);
if (isPotentiallyInOverflow && [self.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *selectedNavController = (UINavigationController *)self.selectedViewController;
NSArray<UIViewController *> *selectedNavControllerStack = [selectedNavController viewControllers];
MoreTabDLog(#"Selected Nav: %#, selectedNavStack: %#", selectedNavController, selectedNavControllerStack);
UIViewController *lastChildVCOfTabBar = [[self childViewControllers] lastObject];
if ([lastChildVCOfTabBar isKindOfClass:[UINavigationController class]] && [NSStringFromClass([lastChildVCOfTabBar class]) hasPrefix:#"UIMore"]) {
/*
Case 2: While in compact width, we are on a tab greater than the 4th and are changing to regular width.
We are going OUT of compact
*/
UINavigationController *moreNavigationController = (UINavigationController *)lastChildVCOfTabBar;
NSArray *moreNavigationControllerStack = [moreNavigationController viewControllers];
MoreTabDLog(#"--- going OUT of compact");
MoreTabDLog(#"moreNav: %#, moreNavStack: %#, targetNavStack: %#", moreNavigationController, moreNavigationControllerStack, selectedNavControllerStack);
if ([moreNavigationControllerStack count] > 1) {
NSArray *fixedTargetStack = [moreNavigationControllerStack subarrayWithRange:NSMakeRange(1, moreNavigationControllerStack.count - 1)];
MoreTabDLog(#"fixedTargetStack: %#", fixedTargetStack);
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *correctVCList = [NSArray arrayWithArray:self.viewControllers];
[selectedNavController willMoveToParentViewController:self];
[selectedNavController setViewControllers:fixedTargetStack animated:NO];
// We need to do this because without it, the selectedNavController doesn't
// have a parentViewController anymore.
[self addChildViewController:selectedNavController];
// We need to do this because otherwise the previous call will cause the given
// Tab to show up twice in the UIMoreListController.
[self setViewControllers:correctVCList];
});
} else {
MoreTabDLog(#"popping to root");
dispatch_async(dispatch_get_main_queue(), ^{
[selectedNavController popToRootViewControllerAnimated:NO];
});
}
} else {
/*
Case 3: While in regular width, we are on a tab greater than the 4th and are changing to compact width.
We are going INTO compact
*/
MoreTabDLog(#"-- going INTO compact");
if ([selectedNavControllerStack count] > 0) {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
// no op
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
UIViewController *parentViewControllerOfTopVC = [[selectedNavControllerStack lastObject] parentViewController];
MoreTabDLog(#"parentViewControllerOfTopVC: %#", parentViewControllerOfTopVC);
if ([parentViewControllerOfTopVC isKindOfClass:[UINavigationController class]] && [NSStringFromClass([parentViewControllerOfTopVC class]) hasPrefix:#"UIMore"]) {
UINavigationController *moreNavigationController = (UINavigationController *)parentViewControllerOfTopVC;
NSArray *moreNavigationControllerStack = [moreNavigationController viewControllers];
BOOL isOriginalRootVCInMoreStack = [moreNavigationControllerStack containsObject:[selectedNavControllerStack firstObject]];
MoreTabDLog(#"moreNav: %#, moreNavStack: %#, isOriginalRootVCInMoreStack: %i", moreNavigationController, moreNavigationControllerStack, isOriginalRootVCInMoreStack);
if (!isOriginalRootVCInMoreStack) {
NSArray *fixedMoreStack = [#[moreNavigationControllerStack[0]] arrayByAddingObjectsFromArray:selectedNavControllerStack];
MoreTabDLog(#"fixedMoreStack: %#", fixedMoreStack);
[selectedNavController setViewControllers:selectedNavControllerStack animated:NO];
dispatch_async(dispatch_get_main_queue(), ^{
[moreNavigationController setViewControllers:fixedMoreStack animated:NO];
});
}
}
}];
}
}
}
}
}
[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
MoreTabDLog(#"-- after willTransitionToTraitCollection");
}
Enjoy!
Johannes
I have found a workaround that seems to get around this issue.
By overriding the UITraitCollection in a UITabBarController subclass you can force the horizontalSizeClass to always be UIUserInterfaceSizeClassCompact. This will make the UITabBar only ever have 5 items regardless of the orientation.
Here some sample Objective-C code:
- (UITraitCollection *)traitCollection {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
// Workaround to fix the iPhone 6 Plus roatation issue.
UITraitCollection *curr = [super traitCollection];
UITraitCollection *compact = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
return [UITraitCollection traitCollectionWithTraitsFromCollections:#[curr, compact]];
}
return [super traitCollection];
}
Then if you need access to real traits then override -traitCollection in your UIViewController to return the traits from [UIScreen mainScreen].
Here some example Objective-C code to do that:
- (UITraitCollection *)traitCollection {
return [UIScreen mainScreen].traitCollection;
}
This not an ideal solution but until Apple decides to fix this bug, this will do the job.
I hope this helps someone.
rdar://21297168
I realize apples documentation suggests a split view should be set as the root view controller. So essentially I have an app with a tab bar. Inside of the first index of the tab bar I have a split view. When the device's orientation is in portrait, I want the (master detail of the split) to fill the whole screen or become the detail page, but more importantly not have the option to have a master detail when the device is in portrait. So my thought is that I swap out tab bar indexes based on the devices orientation. Here's what my code looks like:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if( UIInterfaceOrientationIsLandscape(toInterfaceOrientation) )
{
UISplitViewController * splitview = [[UISplitViewController alloc]init];
//
// splitview.delegate =self;
// [splitview willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
NSLog(#"LandScape!!");
NSMutableArray * array = [MyCustomwViewManager changeHomeOrientationTolandScape:[NSMutableArray arrayWithArray:self.tabBarController.viewControllers] viewController:self navigationController:self.navigationController splitView:splitview];
[self.tabBarController setViewControllers:array animated:YES];
// [self viewDidLoad];
} else {
NSMutableArray * changeSplit = [NSMutableArray arrayWithArray: self.splitViewController.viewControllers];
NSMutableArray * array = [MyCustomViewManager changeHomeOrientationToPortrait:[NSMutableArray arrayWithArray:self.tabBarController.viewControllers] viewController:[changeSplit objectAtIndex:0] navigation:[changeSplit objectAtIndex:0]];
[self.tabBarController setViewControllers:array animated:YES];
}
}
My goal is to achieve something similar to the yelp iPad app. Hopefully I am clear and make sense.
I have a slider in Root UIPageViewController which need to pass the slider value to the child View Controller. Which works for other child view controller except than the one already loaded !
I have Slider in RootView for Slider Value Change I have called -
- (void)sliderValueChanged:(UISlider *)slider {
fontValue = slider.value;
DetailsVC *dataViewController = [self viewControllerAtIndex:self.newsIndex storyboard:self.storyboard];
[dataViewController refreshViewForFontSize:slider.value];
}
I have usual Methods of UIPageViewController which works fine. Just the problem is it works only after the ViewDid Load method is called in child ViewControllers
- (DetailsVC *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard {
// Return the data view controller for the given index.
if (([self.pageContent count] == 0) || (index >= [self.pageContent count])) {
return nil;
}
DetailsVC *dataViewController = [[DetailsVC alloc] init];
dataViewController.fontValue = fontValue;
return dataViewController;
}
Finally found the solution
DetailsVC *dataViewController = [self viewControllerAtIndex:currentIndex-1 storyboard:self.storyboard];
dataViewController.textColor = textColor;
NSArray *viewControllers = #[dataViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
The currect way to get reload the child viewcontroller is to get it via
setViewControllers: direction: animated: completion:
If anyone need a example project I have upload it at
https://github.com/bishalg/BGPageViewController
I am using a split view controller in a simple app. Leaving everything as default works fine. In other words, the master view controller always shows in landscape and overlays the detail view controller in portrait when the back button is pressed.
What I wanted to do was make the master view controller mimic the same functionality in landscape as it does in portrait. In other words, when the device is in landscape, I want the master view controller to be hidden until I hit the back button and then I want it to overlay the detail view controller.
I figured the best way to do this was to use the following code:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return self.bHideMaster;
}
This worked in that it hid the master view controller in landscape mode. I then used the following code to make it reappear:
- (void)hideUnhidePagesController:(id)sender
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.30f];
UISplitViewController* spv = self.splitViewController;
// Change hide to unhide or vica versa
self.bHideMaster= !self.bHideMaster;
// Hide the button if master is visible
if(self.bHideMaster)
{
self.navigationItem.leftBarButtonItem = self.pagesBarButton;
}
else
{
self.navigationItem.leftBarButtonItem = nil;
}
[spv.view setNeedsLayout];
[spv willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
[[self.splitViewController.viewControllers lastObject] view].frame = self.splitViewController.view.frame;
[UIView commitAnimations];
}
This ALMOST worked. I have 2 problems:
The transition from hide-to-unhide and unhide-to-hide the master view controller isn't animated and is much to stark. I added animation code (see above) but it only animates the detail view controller and not the master view controller. The master appears and dis-appears instantly (leaving a black box on disappear) until the detail view controller slides over.
This also shows my second problem. I want the master view controller to overlap the detail view controller when it appears in landscape mode, leaving the detail view controller as is. Instead, it resizes the detail view controller (the same way it does in landscape mode before I started). I want the master view controller to interact the same way it does in portrait mode: Master slides in over the top of the detail controller and slides back out when it an item is selected.
If I could solve problem 2, then I don't have to worry about problem 1. It seems like there should be a method in the split view controller that would slide in the master from the left (overlapping the detail view controller). It does it in portrait mode so the code must be there. How can I call that same code in landscape mode?
Thanks!
---------EDIT 1---------
I have refactored hideUnhidePagesController and am getting closer. The window now overlays in both portrait and landscape. There is still a problem if the master is visible on rotation. It gets confused and inverts the expected behavior. I'm working on it. Here the amended code:
- (void)hideUnhidePagesController:(id)sender
{
// Change hide to unhide or vica versa
self.bMasterIsHidden= !self.bMasterIsHidden;
NSArray *controllers = self.splitViewController.viewControllers;
UIViewController *rootViewController = [controllers objectAtIndex:0];
UIView *rootView = rootViewController.view;
CGRect rootFrame = rootView.frame;
if(self.bMasterIsHidden)
{
rootFrame.origin.x -= rootFrame.size.width;
}
else
{
rootFrame.origin.x += rootFrame.size.width;
}
[UIView beginAnimations:#"hideUnhideView" context:NULL];
rootView.frame = rootFrame;
[UIView commitAnimations];
}
In ios 8.0
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;
to hide master view
To get the effect you describe I had to add the following code to my DetailViewController.
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
Then my split view works the same in portrait and landscape mode.
I'm putting in the code that I ended up using. Hope this helps someone else.
// ***************************************************************************************************
//
// hideUnhideMasterViewControllerButtonPressed
//
// ***************************************************************************************************
- (void)hideUnhideMasterViewControllerButtonPressed:(id)sender {
if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self.navigationController popViewControllerAnimated:YES];
}
else {
if(bMasterIsHidden)
[self hideMasterViewController:NO];
else
[self hideMasterViewController:YES];
}
}
// ***************************************************************************************************
//
// hideMasterViewController
//
// ***************************************************************************************************
- (void)hideMasterViewController:(BOOL)bHideMaster {
// Change hide to unhide or vica versa
self.bMasterIsHidden= !self.bMasterIsHidden;
NSArray *controllers = self.splitViewController.viewControllers;
UIViewController *rootViewController = [controllers objectAtIndex:0];
UIView *rootView = rootViewController.view;
CGRect rootFrame = rootView.frame;
if(bHideMaster) {
if(self.tapRecognizer) {
rootFrame.origin.x -= rootFrame.size.width;
[self.view removeGestureRecognizer:self.tapRecognizer];
self.tapRecognizer = nil;
}
}
else {
rootFrame.origin.x += rootFrame.size.width;
self.tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognized:)];
self.tapRecognizer.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:self.tapRecognizer];
self.tapRecognizer.delegate = self;
}
// Log resulting frame
NSString *hiddenString = self.bMasterIsHidden ? #"YES" : #"NO";
NSLog(#"Page=%# Class=%# MasterIsHidden=%# Origin(x,y)=(%f, %f) Size(width,height)=(%f, %f)", self.pageDefinition.pageName, [self class], hiddenString, rootFrame.origin.x, rootFrame.origin.y, rootFrame.size.width, rootFrame.size.height);
[UIView beginAnimations:#"hideUnhideView" context:NULL];
rootView.frame = rootFrame;
[UIView commitAnimations];
}
Maybe I am too late to answer this but... here is the solution..
You can get the reference of your masterviewcontroller from the method in every orientation change
-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation {
myVCForPopOverController = vc;
//always hide the controller
return YES;
}
now you can show this "myVCForPopOverController" from any barbutton items click.
-(void)onBarButtonClick:(id)sender {
if(!self.popOverController.popoverVisible) {
self.popOverController = [[UIPopoverController alloc]initWithContentViewController:myVCForPopOverController];
[self.popOverController presentPopoverFromBarButtonItem:showDetailsBarButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
self.popOverController.passthroughViews = nil;
}
else {
[self.popOverController dismissPopoverAnimated:YES];
}
}
I have implemented this and it works.