本文介绍了显示/隐藏 UIToolbar,“匹配手指移动",就像在 iOS7 Safari 中一样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:在此处查看 Thuy 的优秀 UINavBar 子类:

您可以这样编程,实现 Apple 示例中的每一条规则,以适应您在每一点上的口味.(当你接近底部时该怎么办,手指向上,哪个方向等等.)我的观点是我只是假设有人已经完成了完全匹配 Apple UX 的所有工作——呵呵!

解决方案

没有开源可以做到这一点,但我不认为它很难实现.像 Safari 那样精确的 1:1 行为可能有点困难,但仍然可以做到.

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

所以这一切都发生在滚动通知之后.

我在 MobileSafari'___lldb_unnamed_function990$$MobileSafari 上放置了一个断点,并获取 self 变量,打印 po $arg1.这就是所有魔法发生的地方:

http://pastebin.com/kjAXKKTW

如果你真的对 1:1 复制感兴趣,你可以在这些方法上设置断点并进行调查.祝你好运!

Note: check out Thuy's great subclass of UINavBar here:

https://stackoverflow.com/a/20720359/294884

If you're working on this problem, GTScrollNavigationBar is close to a ready-made solution to the navBar problem!

For example: on a 2014 iPhone, open Safari, load any web page.

Look at the iOS toolbar at the bottom.

Now move your finger up and down ONLY A FEW PIXELS.

Basically the toolbar at the bottom, moves with your finger. Furthermore, the toolbar later appears/disappears as you scroll the page, following specific logic.

But the interaction rules are very complicated, and involve finger on/off during the hide, distance matching, gestures when you are further down the page, special cases for very short pages, and so on.

I want to EXACTLY duplicate the Apple behaviour.

(It seems sensible that we should match the Apple UX.)

Is there a way to do this? does Apple offer a one-step command for that, which I don't know about? Or do you have to laboriously duplicate the concept?

Thanks.

By the way, the following logic is reliable and will roughly duplicate the way Apple does it:

-(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
}

By the way, of course you can use

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

to slide a UIToolbar up and down. BUT that does not help in any way with "finger matching".

Note: and here for example is a superb solution seen on SO:

https://stackoverflow.com/a/21049991/294884

You could program like that, implementing each and every rule in the Apple example, to suit your taste on each point. (What to do when you are near the bottom, finger up, which direction, etc etc.) My point is I just assumed someone must have done all that work already of matching the Apple UX exactly -- heh!

解决方案

There is no open-source that does this, but I don't see it as that difficult to implement. It may be somewhat more difficult to have the exact 1:1 behavior as Safari, but it can still be done.

MobileSafar can be attached to in the debugger and, using breakpoints and the Objective C runtime, debugged and reverse engineered.

For example, your two assumptions that no toolbar and navigation bars are used are incorrect.

Here is the view hierarchy before scrolling:

http://pastebin.com/aRXr7b5Z

And after scrolling:

http://pastebin.com/CasBNuxq

As you can see, the bars have been moved from their normal location.

Breaking on -[BrowserToolbar setFrame:], here is the stack trace:

* 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

So it all happens after a notification of scrolling.

I put a breakpoint on MobileSafari'___lldb_unnamed_function990$$MobileSafari and to get the self variable, print po $arg1. This is where all the magic happens:

http://pastebin.com/kjAXKKTW

If you are really interested in 1:1 replication, you can put breakpoints on these methods and investigate. Good luck!

这篇关于显示/隐藏 UIToolbar,“匹配手指移动",就像在 iOS7 Safari 中一样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 11:58