Содержимое помещено в UIPageViewController с помощью UINavigationController

ОБНОВЛЕНИЕ 2

Я запускал и тестировал свое приложение в iOS Simulator с помощью 4-дюймового устройства. Если я запускаю с использованием 3,5-дюймового устройства, ярлык не прыгает. В моем .xib, в разделе "Имитированные показатели", я установил его как 4-дюймовый полноэкранный режим Retina. Любая идея, почему я вижу эту проблему только на 4-дюймовом устройстве?

ОБНОВЛЕНИЕ 1

В IB, если я выберу "Панель навигации" в Simulated Metrics, моя метка все еще скачет. Единственный способ, которым я могу заставить свою метку правильно отображать на первом экране, - это не устанавливать контроллер навигации в качестве моего контроллера корневого окна.

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

В моем окне rootViewController устанавливается UINavigationController, у которого rootViewController имеет встроенный UIPageViewController.

Когда мое приложение загружается, исходное представление представлено содержимым, которое немного сдвинуто вниз, примерно того же размера, что и панель навигации. Когда я просматриваю pageViewController, содержимое вскакивает туда, где оно было помещено в nib, и все остальные диспетчеры просмотра, загруженные с помощью pageViewController, являются точными.

uipageviewcontroller with navigationcontroller

В моем приложении 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];
}

Ответ 1

Итак, я добавляю еще один ответ после дальнейшей разработки, и, наконец, я думаю, что понял, что происходит. Кажется, что в iOS7 UIPageViewController имеет свой собственный UIScrollView. Из-за этого вам нужно установить automaticallyAdjustsScrollViewInsets в значение false. Здесь my viewDidLoad сейчас:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.automaticallyAdjustsScrollViewInsets = false;

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

Нет необходимости вставлять что-либо в viewWillLayoutSubviews (как предложил один из моих предыдущих ответов).

Ответ 2

Это определенно вызвано automaticallyAdjustsScrollViewInsets, как и другие плакаты (включая @djibouti33). Однако это свойство выглядит странно двумя способами:

  • Он должен быть установлен на UINavigationController. Если вы установите его на дочернем контроллере, которым управляет UINavigationController, он не будет иметь никакого эффекта. 1
  • Это применимо только тогда, когда представление прокрутки имеет нулевой индекс в подсмотрах контроллера. 2

Эти два оговорки должны объяснять прерывистые проблемы, с которыми сталкиваются другие в потоке.

TL;DR: Обходной путь, с которым я пошел, заключается в добавлении фиктивного представления к UIPageViewController с нулевым индексом, чтобы избежать установки, применяемой к scrollView в контроллере страницы, например:

pageViewController.view.insertSubview(UIView(), atIndex: 0) // swift

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

Лучше было бы установить contentInset в представлении прокрутки самостоятельно, но, к сожалению, UIPageViewController не отображает вид прокрутки.

Ответ 3

Снимите флажок Under Top Bars для обоих: UIPageViewController и вашего пользовательского PageContentViewController:

введите описание изображения здесь

Ответ 4

Мой первоначальный ответ решил проблему на время, но через некоторое время та же проблема вернулась, чтобы укусить меня.

Используя следующую иерархию viewController:

-- UINavigationController
  -- MyPageViewController
    -- MyDetailViewController

Вот что я сделал для его решения:

В 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 child view controller initially if it contained a 
// scroll view. by the time we're in layoutSubviews, pageViewController seems to
// have gotten it bearings and everything is laid out just fine.
- (void)viewWillLayoutSubviews
{
    [self setViewControllers:@[self.initialViewController]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:false
                  completion:nil];
}

Ответ 5

У меня та же проблема. Я решаю его, помещая setViewControllers для первой страницы в UIPageViewController viewDidLoad вместо установки, когда я делаю экземпляр UIPageViewController. Кроме того, мне нужно установить autoAdjustsScrollViewInsets на NO.

Ответ 6

У меня была аналогичная проблема, но ни одно из решений здесь не работало. Моя проблема заключалась в том, что всякий раз, когда я переходил на следующую страницу, содержимое скачкорялось бы, заканчиваясь в правильной позиции, но начиналось с 20 пикселей слишком высоко (явно что-то делать со строкой состояния). Мой контейнер VC не был навигационным VC. Потянув мои волосы на какое-то время, решение, которое в конечном итоге работало на меня, состояло в том, чтобы убедиться, что ни одно из ограничений в моем содержании VC не было подключено к верхнему макету. Это может быть или не быть осуществимо в вашем случае, но в моем было, и это было единственное, что решило скачок контента. Также очень любопытно, что эта проблема проявилась только тогда, когда стиль перехода был настроен на прокрутку. Просто изменив его на страницу curl, проблема исчезла. Но мне нужен свиток. Надеюсь, это поможет кому-то еще.

Ответ 7

Попробуйте снять эти 2 варианта на вашем раскадровке

введите описание изображения здесь

Ответ 8

Попробуйте выбрать PageViewController в раскадровке и снимите флажок "Under Bottom Bars" и "Under Opaque Bars" в инспекторе атрибутов.

Ответ 9

Изначально иерархия диспетчера представлений выглядела так:

-- UINavigationController
  -- MyContainerViewController
    -- UIPageViewController
      -- MyDetailViewController

Я настроил его таким образом, чтобы MyContainerViewController мог управлять панелью инструментов. Я сузил свою проблему до MyContainerViewController, а затем мне пришло в голову, что я даже не нуждаюсь в ней, если я подклассифицирую UIPageViewController. Теперь моя иерархия выглядит так:

-- UINavigationController
  -- MyPageViewController
    -- MyDetailViewController

MyPageViewController управляет им toolbar, и все работает так, как ожидалось, как на 4-дюймовом, так и на 3,5-дюймовом устройстве.

Ответ 10

Как указано в "Bo:": установка self.edgesForExtendedLayout = UIRectEdgeNone; в viewDidLoad MyPageViewController решена проблема. - Bo

Ответ 11

Это моя первая публикация о переполнении стека, но я ищу решение этой проблемы уже более недели.

Вот решение, которое я придумал, надеюсь, что это сработает для кого-то еще с той же проблемой.

Я не уверен, как вы инициализируете свой фрейм для вашего контроллера подробного представления, но я собираюсь предположить, что вы можете использовать: self.view.frame.size.height;

попробуйте использовать: self.view.frame.size.height - = self.navigationController.navigationBar.bounds.size.height;

Надеюсь, что это поможет

Ответ 12

Я вижу ту же проблему, что и описанную @Danny на iOS 9. Я попробовал обновить все мои ограничения, чтобы они были не ограничивается полями, но проблема не устранена. В итоге мне пришлось перенести хак, похожий на этот следующим образом:

  • Для каждой страницы содержимого, отображаемой в UIPageViewController, найдите самое верхнее ограничение, которое находится между верхней частью представления и нижней частью верхнего руководства по макете, и добавьте выход для него в контроллер вида.
  • В каждом представлении контроллера с таким выходом добавьте другое свойство для предпочтительного верхнего расстояния. Эти два выхода выглядят следующим образом (в Swift):

    @IBOutlet weak var topGuideConstraint: NSLayoutConstraint!
    var topDistance: CGFloat!
    
  • В viewDidLoad() установите topDistance значение, присвоенное ограничению в раскадровке:

    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.

Это неудачный взлом, и я ненавижу делать это, но после многих часов, пытаясь по-другому, я, по крайней мере, рад, что у меня есть что-то, что работает, чтобы я мог двигаться дальше.

Ответ 13

Как уже писал @djibouti33:

aПросмотр страницыПросмотр не мог надлежащим образом выложите его контроллер дочернего представления, если он содержит просмотр прокрутки. к тому времени, когда мы находимся в 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)
}

Ответ 14

Никто из них не работал у меня

Здесь я нашел решение

var pageMenu : CAPSPageMenu?

Вместо добавления как это

self.view.addSubview(pageMenu!.view)

Добавьте свой CAPSPageMenu, как показано ниже

addChildViewController(pageMenu!) 
self.view.addSubview(pageMenu!.view) 
pageMenu!.didMove(toParentViewController: self)

Ссылка: iOS Swift: SlidingMenuView неправильное положение после представления imagePicker

Счастливое кодирование!

Ответ 15

Быстрая версия ответа djibouti33 (исключая строку, которая не является частью разрешения проблемы)

Swift 3.0

override func viewDidLoad() {
    super.viewDidLoad()
    self.automaticallyAdjustsScrollViewInsets = false
}