Содержание толкнул вниз в UIPageViewController с UINavigationController



обновление 2



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



обновление 1



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



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



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



когда мое приложение загружается, первоначальный вид представлен с его содержимым, сдвинутым немного вниз, примерно такого же размера, как панель навигации. Когда я прокручиваю pageViewController, содержимое перескакивает туда, где оно было помещено в перо, и все другие viewControllers, загруженные 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];
}
610   15  

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). Однако это свойство странно в двух отношениях:

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

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

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

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

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

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

просто снимите флажок Under Top Bars для: UIPageViewController и PageContentViewController:

enter image description here

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

используя следующую иерархию 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, проблема исчезла. Но мне нужен был свиток. Надеюсь, это поможет кому-то еще.

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

enter image description here

попробуйте выбрать 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(), set 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.

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

Как @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

    Ничего не найдено.