Показать/скрыть 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) {}];
});