Содержание толкнул вниз в UIPageViewController с UINavigationController
обновление 2
я запускал и тестировал свое приложение в симуляторе iOS с помощью 4-дюймового устройства. Если я запускаю с помощью 3.5-дюймового устройства, метка не прыгает. В моем.xib, под моделируемыми метриками, я установил его как Retina 4-дюймовый полный экран. Есть идеи, почему я вижу эту проблему только на 4-дюймовом устройстве?
обновление 1
В IB, если я выберу "панель навигации" в смоделированных метриках, моя метка все еще прыгает. Единственный способ, которым я могу получить моя метка для правильного отображения на первом экране не должна устанавливать навигационный контроллер в качестве корневого контроллера вида моего окна.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rootViewController моего окна устанавливается в UINavigationController, чей rootViewController имеет встроенный UIPageViewController.
когда мое приложение загружается, первоначальный вид представлен с его содержимым, сдвинутым немного вниз, примерно такого же размера, как панель навигации. Когда я прокручиваю pageViewController, содержимое перескакивает туда, где оно было помещено в перо, и все другие viewControllers, загруженные pageViewController, в порядке.

в моем appDelegate:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]];
В 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];
}
15 ответов:
поэтому я добавляю еще один ответ после дальнейшего развития, и я, наконец, думаю, что понял, что происходит. Похоже, что в iOS7, UIPageViewController имеет свой собственный UIScrollView. Из-за этого, вы должны установить
automaticallyAdjustsScrollViewInsetsзначение false. Вот мойviewDidLoadтеперь:- (void)viewDidLoad { [super viewDidLoad]; self.automaticallyAdjustsScrollViewInsets = false; DetailViewController *detail = [[DetailViewController alloc] init]; [self setViewControllers:@[detail] direction:UIPageViewControllerNavigationDirectionForward animated:false completion:nil]; }не нужно ничего ставить в
viewWillLayoutSubviews(как один из моих предыдущих ответов предложил).
это, безусловно, была вызвана
automaticallyAdjustsScrollViewInsets, как и другие плакаты (в том числе @djibouti33). Однако это свойство странно в двух отношениях:
- он должен быть установлен на
UINavigationController. Если вы установите его на дочернем контроллере, который управляетсяUINavigationController, это не будет иметь никакого эффекта. 1- он применяется только тогда, когда вид прокрутки находится в нулевом индексе в подвидах контроллера. 2
эти два вопроса должны объяснить периодические проблемы, с которыми сталкиваются другие в теме.
TLDR: обходной путь, с которым я пошел, добавляет фиктивный вид в
UIPageViewControllerпри нулевом индексе, чтобы избежать установки, применяемой к scrollView в контроллере страницы, например:pageViewController.view.insertSubview(UIView(), atIndex: 0) // swift [pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-cлучше было бы установить
contentInsetна экране прокрутки себя, но, к сожалению,UIPageViewControllerне предоставляет вид прокрутки.
мой оригинальный ответ решил проблему на время, но через некоторое время та же проблема может вернуться, чтобы укусить меня.
используя следующую иерархию viewController:
-- UINavigationController -- MyPageViewController -- MyDetailViewControllerвот что я сделал, чтобы решить это:
В MyPageViewController.м
@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]; }
У меня та же проблема. Я решаю это, помещая setViewControllers для первой страницы в viewDidLoad UIPageViewController вместо того, чтобы устанавливать его, когда я делаю экземпляр UIPageViewController. Кроме того, мне нужно установить automaticallyAdjustsScrollViewInsets в NO.
У меня была похожая проблема, но ни одно из решений здесь работал. Моя проблема заключалась в том, что всякий раз, когда я прокручивал следующую страницу, содержимое прыгало вниз, заканчиваясь в правильном положении, но начиная с 20 пикселей слишком высоко (очевидно, что-то связано со строкой состояния). Мой контейнер VC не был навигационным VC. После того, как я вытащил волосы на некоторое время, решение, которое в конечном итоге работало для меня, состояло в том, чтобы убедиться, что ни одно из ограничений в моем контенте VC не было связано с верхним руководством по макету. Это может быть или не быть возможным в вашем случае, но в моем это было, и это было единственное, что решило скачок содержания. Также очень любопытно, что эта проблема проявляется только когда переход был свиток. Просто изменив его на Page curl, проблема исчезла. Но мне нужен был свиток. Надеюсь, это поможет кому-то еще.
попробуйте выбрать PageViewController в раскадровке и снимите флажки "под нижними полосами" и "под непрозрачными полосами" в Инспекторе атрибутов.
изначально моя иерархия контроллера вида выглядела так:
-- UINavigationController -- MyContainerViewController -- UIPageViewController -- MyDetailViewControllerЯ настроил его таким образом, чтобы MyContainerViewController мог управлять панелью инструментов. Я сузил свою проблему до MyContainerViewController, а затем мне пришло в голову, что мне это даже не нужно, если я подкласс UIPageViewController. Теперь моя иерархия выглядит так:
-- UINavigationController -- MyPageViewController -- MyDetailViewController
MyPageViewControllerуправляет этоtoolbar, и все работает как ожидалось, как на 4-дюймовом, так и на 3,5-дюймовом устройстве.
Как указано "Бо:": положить себя.edgesForExtendedLayout = UIRectEdgeNone; в viewDidLoad MyPageViewController решена проблема. - Бо
Это моя первая публикация в Stack overflow, но я уже более недели ищу решение этой проблемы.
вот решение, которое я придумал, я надеюсь, что это работает для кого-то еще с той же проблемой.
Я не уверен, как вы инициализируете свой фрейм для вашего контроллера детального вида, но я предполагаю, что вы можете использовать: self.вид.рамка.размер.высота;
попробуйте использовать: self.вид.рамка.размер.высота=- личность.navigationController.навигационная панель.границы.размер.высота;
надеюсь, что это помогает
Я вижу ту же проблему, что и описано @Danny на iOS 9. Я попытался обновить все мои ограничения, чтобы они были не ограничены полями, но это не решило проблему. В итоге мне пришлось принять Хак, похожий на этот следующим образом:
- для каждой страницы содержимого, которая будет отображаться в UIPageViewController, найдите самое верхнее ограничение, которое находится между верхней частью представления и нижней частью верхнего руководства по компоновке, и добавьте выход для него в контроллер вида.
в каждом контроллере вида с такой розеткой добавьте другое свойство для предпочтительного верхнего расстояния. Два выхода выглядят так (в Swift):
@IBOutlet weak var topGuideConstraint: NSLayoutConstraint! var topDistance: CGFloat!на
viewDidLoad(), settopDistanceк значению, присвоенному ограничению в раскадровке:override func viewDidLoad() { super.viewDidLoad() topDistance = topGuideConstraint.constant }на
viewWillLayoutSubviews(), убедитесь, что ограничение имеет правильное значение, регулируя высоту строки состояния когдаtopLayoutGuide.lengthравно нулю, что, кажется, так при переходе, но не сразу он будет завершен:override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() topGuideConstraint.constant = topDistance + ( topLayoutGuide.length == 0 ? UIApplication.sharedApplication().statusBarFrame.size.height : 0 ) }повторите для каждого контроллера представления содержимого, отображаемого в UIPageViewController. Отрегулируйте смещение соответствующим образом, если вы также показываете панель UINavigation.
это неудачный Хак, и я ненавижу делать это, но после многих часов, пытаясь разные вещи, я, по крайней мере, счастлив иметь что-то, что работает так что я могу двигаться дальше.
Как @djibouti33 уже написал:
pageViewController не смог правильно выложите это дочерний контроллер вида изначально, если он содержал вид прокрутки. к тому времени, когда мы находимся в layoutSubviews, pageViewController, похоже, получил его подшипники, и все выложено просто отлично
ожидая загрузки layoutSubViews перед установкой любых viewControllers в UIPageViewController было единственным, что работало мне.
override func viewDidLoad() { super.viewDidLoad() self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "yourPageViewController") as? UIPageViewController self.pageViewController?.dataSource = self pageViewController?.automaticallyAdjustsScrollViewInsets = false self.pageViewController?.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.height) self.addChildViewController(self.pageViewController!) self.view.addSubview((self.pageViewController?.view)!) self.pageViewController?.didMove(toParentViewController: self) } override func viewDidLayoutSubviews() { let startVC = self.viewControllerAtIndex(index: 0) as infoDataViewController let viewControllers = NSArray(object: startVC) self.pageViewController?.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil) }
никто из вышеперечисленных не работал для меня
здесь я нашел решение
var pageMenu : CAPSPageMenu?вместо того, чтобы добавлять такой
self.view.addSubview(pageMenu!.view)Добавить свой CAPSPageMenu, как показано ниже
addChildViewController(pageMenu!) self.view.addSubview(pageMenu!.view) pageMenu!.didMove(toParentViewController: self)ссылки: iOS Swift: SlidingMenuView неправильное положение после представления imagePicker
Удачи В Кодировании!
версия Swift ответа джибути33 (исключая строку, которая не является частью решения проблемы)
Swift 3.0
override func viewDidLoad() { super.viewDidLoad() self.automaticallyAdjustsScrollViewInsets = false }


Comments