您的位置:首页 > 产品设计 > UI/UE

UINavigation嵌套UIpageViewController时视图会下移到UInavigationBar下面

2015-04-08 00:02 417 查看


Content
pushed down in a UIPageViewController with UINavigationController

up
vote24down
votefavorite
8

UPDATE 2

I've been running and testing my app in the iOS Simulator using a 4-inch device. If I run using a 3.5-inch device the label doesn't jump. In my .xib, under Simulated Metrics, I have it set as Retina 4-inch Full Screen. Any idea why I'm only seeing this problem
on a 4-inch device?

UPDATE 1

In IB, if I choose "Navigation Bar" in Simulated Metrics, my label still jumps. The only way I can get my label to render correctly on the first screen is to not set a navigation controller as my window's root view controller.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

My window's rootViewController is being set to a UINavigationController whose rootViewController has a UIPageViewController embedded.

When my app loads, the initial view is presented with it's content pushed down a bit, roughly the same size as a navigation bar. When I scroll the pageViewController, the content jumps up to where it was placed in the nib, and all other viewControllers loaded
by the pageViewController are fine.



In my appDelegate:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]];


In ContainerViewController:
- (void)viewDidLoad {

[super viewDidLoad];

self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pvc.dataSource = self;
self.pvc.delegate = self;
DetailViewController *detail = [DetailViewController new];
[self.pvc setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];

[self addChildViewController:self.pvc];
[self.view addSubview:self.pvc.view];
[self.pvc didMoveToParentViewController:self];
}


iphone ios objective-c uinavigationcontroller uipageviewcontroller
shareedit
edited Aug
13 '13 at 20:54

asked Aug 13 '13 at 6:52





djibouti33
5,12934066

 
 
while designing the interface (.xib file) in the "attribute inspector" tab select top bar as "Navigation Bar" from drop
down and then put your label accordingly in this way the label will be as it's original place. – Gyanendra
Singh Aug
13 '13 at 7:29
 
That's actually what I'm already doing. –  djibouti33 Aug
13 '13 at 9:22
add
a comment


7 Answers

activeoldestvotes

up vote0down
vote
this is my first time posting on stack overflow, but I have searching for a solution to this problem for over a week now.

Here is a solution I came up with, I hope this works for anyone else with the same issue.

I'm not sure how you are initializing your frame for your detail view controller, but I am going to assume you might use: self.view.frame.size.height;

try using: self.view.frame.size.height -= self.navigationController.navigationBar.bounds.size.height;

Hope this helps

shareedit
answered Apr 2 at 1:58





user3753234
1

 add
a comment
up vote1down
vote
I have the same problem. I solve it by putting setViewControllers for the first page in UIPageViewController's viewDidLoad instead of setting it when I make a instance of UIPageViewController. Also, I need to set automaticallyAdjustsScrollViewInsets to NO.

shareedit
answered Mar 25 at 19:17





howa
362

 add
a comment
up vote0down
vote
As stated by "Bo:": Putting self.edgesForExtendedLayout = UIRectEdgeNone; in the viewDidLoad of MyPageViewController solved the problem. – Bo

shareedit
answered Mar 2 at 9:34





osxdirk
34528

 add
a comment
up vote5down
vote
This is definitely being caused by 
automaticallyAdjustsScrollViewInsets
,
as other posters (including @djibouti33). However, this property is strange in two ways:
It must be set on a 
UINavigationController
.
If you set it on a child controller that's managed by a 
UINavigationController
,
it won't have any effect. 1
It only applies when a scroll view is at index zero in a controller's subviews. 2

These two caveats should explain the intermittent problems experienced by others in the thread.

TLDR: A workaround that I went with is adding a dummy view to the 
UIPageViewController
 at
index zero, to avoid the setting applying to the scrollView within the page controller, like this:
pageViewController.view.insertSubview(UIView(), atIndex: 0) // swift

[pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-c


Better would be to set the 
contentInset
 on
the scroll view yourself, but unfortunately the 
UIPageViewController
 doesn't
expose the scroll view.

shareedit
answered Nov 17 '14 at 20:19




John Gibb
5,0241530

 
 
This is a little hacky way. –  kelin Jan
15 at 16:08
 
hacky. but works! thanks –  TonyTakeshi Jan
28 at 5:07 
 
definitely hacky. but so is this magic behavior depending on a scrollview being at index zero! –  John
GibbJan
28 at 23:08
add
a comment
up vote22down
voteaccepted
So I'm adding another answer after further development and I finally think I figured out what's going on. Seems as though in iOS7, UIPageViewController has its own UIScrollView. Because of this, you have to set 
automaticallyAdjustsScrollViewInsets
 to
false. Here's my 
viewDidLoad
now:
- (void)viewDidLoad
{
[super viewDidLoad];

self.automaticallyAdjustsScrollViewInsets = false;

DetailViewController *detail = [[DetailViewController alloc] init];
[self setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}


No need to put anything in 
viewWillLayoutSubviews
 (as
one of my previous answers suggested).

shareedit
answered Nov 14 '13 at 21:50





djibouti33
5,12934066

 
1 
See my caveat below that 
automaticallyAdjustsScrollViewInsets
 won't
do anything when applied to a child view controller, such as a view controller inside of a 
UINavigationViewController
 or
a
UITabBarController
 –  John
Gibb Nov
17 '14 at 20:21
add
a comment
up vote3down
vote
My original answer solved the problem for the time being, but after a while the same problem came back to bite me.

Using the following viewController hierarchy:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController


Here's what I did to solve it:

In MyPageViewController.m
@interface MyPageViewController () <delegates>
@property (strong) MyDetailViewController *initialViewController;
@end

- (void)viewDidLoad
{
...

// set this once, because we're going to use it in viewWillLayoutSubviews,
// which gets called multiple times
self.initialViewController = [MyDetailViewController new];
}

// the problem seemed to stem from the fact that a pageViewController couldn't
// properly lay out it's child view controller initially if it contained a
// scroll view. by the time we're in layoutSubviews, pageViewController seems to
// have gotten it's bearings and everything is laid out just fine.
- (void)viewWillLayoutSubviews
{
[self setViewControllers:@[self.initialViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}


shareedit
answered Sep 27 '13 at 21:11





djibouti33
5,12934066

 
 
This is the one that ended up working for me - self.automaticallyAdjustsScrollViewInsets = false; didn't seem to do
anything. –  Adama Sep
11 '14 at 15:53
 
@djibouti33: I think I figured out what was going on, see stackoverflow.com/a/26981213/99046 –  John
GibbNov
17 '14 at 20:19
 
this worked for me - especially with a hierarchy that has detail view controllers embedded in their own nav controllers –  Terry
Bu Jan
19 at 20:25
add
a comment
up vote0down
vote
Initially my view controller hierarchy looked like this:
-- UINavigationController
-- MyContainerViewController
-- UIPageViewController
-- MyDetailViewController


I set it up this way so MyContainerViewController could manage a toolbar. I narrowed my problem down to MyContainerViewController, and then it occurred to me that I don't even need it if I subclass UIPageViewController. Now my hierarchy looks like this:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController


MyPageViewController
 manages
it's 
toolbar
,
and everything works as expected, both on a 4-inch and 3.5-inch device.

shareedit
answered Aug 14 '13 at 16:09





djibouti33
5,12934066

 
1 
For me, adopting this hierarchy is not enough. Putting self.edgesForExtendedLayout = UIRectEdgeNone; in the viewDidLoad
of MyPageViewController solved the problem. –  Bo. Sep
21 '13 at 15:54
 
Hey Bo, check out my new answer, which I chose as the accepted answer. Turns out that adopting this new hierarchy didn't
quite solve it for me, as the problem came back again later in development. I also wanted my scrollviews to scroll underneath the blurred navigation bar, so I couldn't use your advice regarding edgesForExtendedLayout. My new answer seems to be solid though. –  djibouti33 Sep
27 '13 at 21:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息