Подтвердить что ты не робот

Переход iOS7 Custom ViewController и руководство Top Layout

Я реализовал пользовательский переход UIViewController в моем приложении, который заменяет контроллеры навигации, созданные в push-анимации.

Все работает до сих пор, за исключением того, что toplayoutguide в контроллере нового толкаемого изображения равен 0, хотя новый контроллер представления унаследовал навигационную панель от старого контроллера представлений. Он должен быть 64.0 (высота панели управления + высота панели навигации), где сейчас 0.0. Таким образом, все объекты, которые прикреплены к верхней направляющей макета в раскадровке, теперь выглядят на 64 очка слишком высокими (ниже полупрозрачной панели).

Когда я отключу пользовательский переход View, верхнее руководство по макету будет иметь ожидаемое значение. Я попытался вызвать layoutSubviews и updateConstraints "повсюду". В контроллере представления, а также в навигационном контроллере.

Насколько я понимаю, диспетчер навигации (parentviewcontroller) должен обновить toplayoutguide нового контроллера представлений, но, видимо, мне не хватает чего-то в моем настраиваемом коде перехода, который запускает обновление до правильного значения для toplayoutguide.

Здесь мой пользовательский код перехода, который является объектом, установленным как делегат навигационного контроллера:

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.7;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIView *animationContainerView = [transitionContext containerView];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *toView = [toVC view];
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *fromView = [fromVC view];

    CGRect endFrame = [transitionContext finalFrameForViewController:toVC];
    CGRect startFrame;

    startFrame = CGRectOffset(endFrame, 0, endFrame.size.height);

    if (self.operation == UINavigationControllerOperationPop) {
        [animationContainerView insertSubview:toView belowSubview:fromView];
        [toView setFrame:endFrame];
    }
    else{
        [toView setFrame:startFrame];
        [animationContainerView insertSubview:toView aboveSubview:fromView];
    }

    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.8 options:UIViewAnimationOptionBeginFromCurrentState animations:^{

        if (self.operation == UINavigationControllerOperationPop) {
            [fromView setFrame:startFrame];
            [fromView layoutIfNeeded];
        }
        else{
            [toView setFrame:endFrame];
            [toView layoutIfNeeded];
        }

    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

Ничего необычного там не бывает. Только вид скользит снизу вверх с некоторой встроенной динамикой.

Проблема заключается в том, что объекты, прикрепленные к верхнему руководству по макету, теперь находятся под панелью навигации, так как длина верхнего направляющего макета == 0.

Я не могу понять, что мне нужно сделать, так что контроллер воспроизведения toplayoutguide установлен на правильное значение.

Навигационная навигация выполняется "plain vanilla" с помощью раскадровки. Все, что я делаю, перед вызовом функции performSegueWithIdentifier - это настроить делегацию диспетчеров навигации.

Здесь код:

    self.navigationController.delegate = [[My_CustomNavigationTransitionDelegate alloc] init];
    [self performSegueWithIdentifier:@"infosSegue" sender:nil];

Что мне не хватает?

4b9b3361

Ответ 1

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

Вы смотрели на это

[self.navigationController.view setNeedsLayout]

Я поместил его в мой viewwillappear, и я прекратил получать нулевую длину в свойстве bottomLayoutGuide. Возможно, это тоже поможет вам с вашим свойством topLayoutGuide.

Ответ 2

Мне удалось обойти это, со следующей иерархией представлений:

UIView
 UIScrollView
  <content, constrained to UIScrollView>

Ограничьте UIScrollView в соответствии с верхними, ведущими, конечными и нижними краями UIView's. Интерфейс Builder может захотеть, чтобы вы использовали topLayoutGuide и bottomLayoutGuide для UIScrollView, иначе это может быть не так. Возможно, это зависит от версии Xcode, но некоторые из наших контроллеров View использовали супервизор, другие использовали макеты.

Для представлений, в которых Interface Builder не хотел ограничивать представление прокрутки относительно своего супервизора, я открыл раскадровку в текстовом редакторе и скорректировал ограничения на просмотр прокрутки вручную.

Наконец, на контроллере просмотра убедитесь, что длина ребер под верхним баром равна YES, а также "Настроить прокрутки".

В принципе, я избегаю использования topLayoutGuide и вместо этого полагаюсь на вставки прокрутки, которые работают.

Где у меня не было UIScrollView в иерархии, как и вы, НЕ расширяя края под верхним баром, работающим для меня.

Ответ 3

Я столкнулся с одной и той же проблемой. У моего настраиваемого диспетчера навигации вид контейнера не было ограничений. В ту минуту, когда я добавил ограничения вертикального расстояния из представления контейнера в его макеты руководства по супервизу (хотя они были одинаковыми по размеру), и установите верхнюю/нижнюю/статусную строку в представлении контейнера , все было в порядке и направляющие макета толкаемых контроллеров находились в правильном положении. Надеюсь, что это поможет.

Обновление: из официальная документация по topLayoutGuide

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

Таким образом, представление контейнера должно реализовывать правильные ограничения и скрывать/показывать бары, а также для того, чтобы эффекты работали. AFAIK нет API для этого в пользовательских контроллерах представления контейнеров.

Ответ 4

Я нашел способ. Сначала снимите флажок "Extend Edges" свойства контроллера после того, как эта панель навигации станет в темном цвете. Добавьте представление к контроллеру и установите верхний и нижний LayoutConstraint -100. Затем сделайте представление свойства clipubview no (для транскулентного эффекта navigaionbar). Мой английский плохой извините за это.:)