Показать/скрыть UIToolbar, "перемещать пальцы", точно так же, как, например, в iOS7 Safari

Примечание: посмотрите Thuy большой подкласс UINavBar здесь:

qaru.site/info/47751/...

Если вы работаете над этой проблемой, GTScrollNavigationBar близок к готовому решению проблемы navBar!


50 пунктов баунти здесь, удивительно, нет ответов.

Например: на iPhone 2014 откройте Safari, загрузите любую веб-страницу.

Посмотрите на панель инструментов iOS внизу.

Теперь переместите палец вверх и вниз ТОЛЬКО НЕСКОЛЬКИХ ПИКСЕЛЕЙ.

enter image description here

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

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

Я хочу, чтобы ТОЧНО дублировал поведение Apple.

(Кажется разумным, что мы должны соответствовать Apple UX.)

Есть ли способ сделать это? Apple предлагает одноступенчатую команду для этого, о которой я не знаю? Или вам нужно тщательно продумывать концепцию?

Спасибо.

Кстати, следующая логика надежна и будет грубо дублировать, как это делает Apple:

-(void)feedIsScrolled:(CGFloat)scrollNewOverallYPosition
{
// call this routine when scrollViewDidScroll:

self.feedIsScrolledDelta =
 scrollNewOverallYPosition - self.feedIsScrolledPrevious;
self.feedIsScrolledPrevious =
 scrollNewOverallYPosition;

// nb, you do those only in this routine, NOT the following routine.

if ( scrollNewOverallYPosition < 15.0 )
    {
    .. animate in the bar
    return;
    }

if ( self.feedIsScrolledDelta > 0.0 )
    .. animate away the bar
}

-(void)feedIsThrown:(CGFloat)scrollNewOverallYPosition
{
// call this routine when scrollViewDidEndDragging:
// BUT ONLY when willDecelerate: is true

if ( self.feedIsScrolledDelta <= 0.0 )
    .. animate in the bar
else
    .. animate away the bar
}

Кстати, вы можете использовать

(void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated

сдвинуть UIToolbar вверх и вниз. НО это никоим образом не помогает с "сопоставлением пальцев".

Примечание: и вот, например, это превосходное решение, увиденное на SO:

qaru.site/info/47751/...

Вы можете запрограммировать это, применяя каждое правило в примере Apple, чтобы удовлетворить ваш вкус в каждой точке. (Что делать, когда вы приближаетесь к низу, пальцем вверх, в каком направлении и т.д.). Я полагаю, что кто-то, должно быть, сделал все, что работает уже , соответствующее Apple UX точно - хе!

Ответ 1

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

MobileSafar может быть подключен к отладчику и, используя точки останова и времени выполнения Objective C, отлаживается и реверсируется.

Например, ваши два предположения о том, что панель инструментов и панели навигации не используются, являются неправильными.

Вот иерархия представлений перед прокруткой:

http://pastebin.com/aRXr7b5Z

И после прокрутки:

http://pastebin.com/CasBNuxq

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

Разрыв -[BrowserToolbar setFrame:], вот трассировка стека:

* thread #1: tid = 0x2332c, 0x000000010003fa70 MobileSafari`___lldb_unnamed_function1519$$MobileSafari, queue = 'com.apple.main-thread', stop reason = breakpoint 8.1
  * frame #0: 0x000000010003fa70 MobileSafari`___lldb_unnamed_function1519$$MobileSafari
    frame #1: 0x0000000100023e51 MobileSafari`___lldb_unnamed_function825$$MobileSafari + 1338
    frame #2: 0x00000001000268da MobileSafari`___lldb_unnamed_function871$$MobileSafari + 55
    frame #3: 0x000000010009856a MobileSafari`___lldb_unnamed_function3864$$MobileSafari + 388
    frame #4: 0x0000000100098996 MobileSafari`___lldb_unnamed_function3871$$MobileSafari + 154
    frame #5: 0x000000010002ba89 MobileSafari`___lldb_unnamed_function990$$MobileSafari + 209
    frame #6: 0x0000000102396a8c UIKit`-[UIScrollView(UIScrollViewInternal) _notifyDidScroll] + 55
    frame #7: 0x000000010238692b UIKit`-[UIScrollView setContentOffset:] + 628
    frame #8: 0x000000010238ab00 UIKit`-[UIScrollView _updatePanGesture] + 1989
    frame #9: 0x0000000102644002 UIKit`_UIGestureRecognizerSendActions + 188
    frame #10: 0x0000000102642f68 UIKit`-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 357
    frame #11: 0x0000000102647319 UIKit`___UIGestureRecognizerUpdate_block_invoke + 53
    frame #12: 0x00000001026472a1 UIKit`_UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 257
    frame #13: 0x000000010263f377 UIKit`_UIGestureRecognizerUpdate + 93
    frame #14: 0x0000000102353e55 UIKit`-[UIWindow _sendGesturesForEvent:] + 928
    frame #15: 0x0000000102354b14 UIKit`-[UIWindow sendEvent:] + 909
    frame #16: 0x000000010232c6da UIKit`-[UIApplication sendEvent:] + 211
    frame #17: 0x0000000102319f2d UIKit`_UIApplicationHandleEventQueue + 9579
    frame #18: 0x0000000100573f21 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #19: 0x00000001005737f2 CoreFoundation`__CFRunLoopDoSources0 + 242
    frame #20: 0x000000010058f66f CoreFoundation`__CFRunLoopRun + 767
    frame #21: 0x000000010058ef83 CoreFoundation`CFRunLoopRunSpecific + 467
    frame #22: 0x00000001011a0f04 GraphicsServices`GSEventRunModal + 161
    frame #23: 0x000000010231c273 UIKit`UIApplicationMain + 1010
    frame #24: 0x00000001000518d2 MobileSafari`___lldb_unnamed_function1998$$MobileSafari + 1558

Итак, все происходит после уведомления прокрутки.

Я поставил точку останова на MobileSafari'___lldb_unnamed_function990$$MobileSafari и чтобы получить переменную self, напечатайте po $arg1. Здесь происходит вся магия:

http://pastebin.com/kjAXKKTW

Если вы действительно заинтересованы в репликации 1:1, вы можете поставить контрольные точки на эти методы и исследовать. Удачи!

Ответ 2

Я просто потянул запрос в GTScrollNavigationBar, который помогает получить правильное "движение пальца". Хитрость - это просто настроить ContentInsets в соответствии с рамкой полосы прокрутки.

Возможно, он еще не идеален, но он делает то, что вы ищете: https://github.com/luugiathuy/GTScrollNavigationBar/pull/21

Ответ 3

Я использовал следующий код, чтобы скрыть tabBar, как в приложении Safari. Возможно, вы или другие люди можете использовать его с toolBar.

static CGFloat navBarOriginY = 20.0;

Создать константу для базового значения начала навигационной панели Y-позиция

- (void)viewDidLoad {
[super viewDidLoad];
 self.navigationController.hidesBarsOnSwipe = true;
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
}

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

- (void)swipe:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateFailed) {

//If gesture state ended/canceled or failed you need entirely change frame of tabBar

    CGRect finalFrame = self.tabBarController.tabBar.frame;
    if (self.navigationController.navigationBar.frame.origin.y < 0) {
         //Tab bar will be hidden
        finalFrame.origin.y = self.maxTabBarY;
    } else {
         //Tab bar will be visible
        finalFrame.origin.y = self.minTabBarY;
    }

    [self setFrameForTabBar:finalFrame animationDuration:0.3];

} else if (recognizer.state == UIGestureRecognizerStateChanged) {

//If state == changed than you need to pan your tabBar with navBar like in safari app.

    CGRect frame = self.tabBarController.tabBar.frame;
    CGFloat delta = navBarOriginY - self.navigationController.navigationBar.layer.presentationLayer.frame.origin.y;
    frame.origin.y = self.minTabBarY + delta;
    [self setFrameForTabBar:frame animationDuration:0.0];
} } }

- (void)setFrameForTabBar:(CGRect)frame animationDuration:(CGFloat)duration {
dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
        self.tabBarController.tabBar.frame = frame;
    } completion:^(BOOL finished) {}];
});