iPhone 的 UIView 的自定义滚动条(让长滚动不那么糟糕)

发布于 2024-10-05 21:29:19 字数 1012 浏览 0 评论 0原文

在一篇文章中,在iPhone Not Suck,Aza Raskin 描述了一种替代滚动条控件,该控件更适合在很长的页面上浏览:

Sticky Scroll Indicator

滚动条“保留一段时间”来激活它并不重要;我只需沿着 iPhone 屏幕的右边缘滑动即可抓住滚动条手柄。这个想法是,如果我将手柄在物理屏幕上向下拖动 3/4,我就会在页面上向下拖动 3/4。

Dropbox iPhone 应用程序(顺便说一句,这太棒了!) 正是针对长 PDF 文档提供了这种滚动条。常规滚动是通过拖动手柄以外的任意位置来完成的;拖动手柄会将视图移动到该位置。这似乎是“从头开始”实现的,因为我认为 SDK 不够灵活,无法自定义现有滚动条的行为。

然而,Dropbox 使用本机文档查看器在 iPhone 上显示文档,因此他们以某种方式为其添加了滚动条功能。看到滚动条手柄了吗?您可以将其拖动以快速到达文档中的其他位置。

Dropbox 滚动条位于顶部 Dropbox 滚动条位于底部

这个概念非常类似于 UITableView 中索引栏的工作方式(即联系人.应用程序);索引在表格右侧显示为条形(例如,“a”到“z”),您可以触摸特定标签以跳转到目标部分。然而,在这种情况下,很长的页面没有部分,它应该适用于通用滚动,而不是跳转到部分。

那么我该如何实现这种滚动方法呢?我正在寻找一般想法和具体实施细节。我也对是否存在开源实现感兴趣(这似乎是一个通用问题/解决方案)。

In a post, Making Long Scrolls on the iPhone Not Suck, Aza Raskin describes an alternative scrollbar control that's better at getting around on very long pages:

Sticky Scroll Indicator

It's not important that the scrollbar "remains for some amount of time" to activate it; I'm fine with simply swiping along the right edge of the iPhone's screen to grab hold of the scrollbar handle. The idea is that if I drag the handle 3/4 of the way down on the physical screen, I'd be 3/4 of the way down on the page.

Tthe Dropbox iPhone app (it's great, btw!) has exactly this kind of scrollbar for long PDF documents. Regular scrolling is done by dragging anywhere but on the handle; dragging the handle moves the view to that location. This seems to have been implemented "from scratch", as I don't think the SDK is flexible enough to customize the behavior of the existing scrollbar.

However, Dropbox uses the native document viewers to show documents on the iPhone, so somehow they add the scrollbar functionality to it. See the scrollbar handle? You can drag that to quickly get somewhere else in the document.

Dropbox scrollbar at the top
Dropbox scrollbar at the bottom

This concept is very similar to how index bars work in UITableView (ie. Contacts.app); the index appears as a bar on the right hand side of the table (for example, "a" through "z"), and you can touch a particular label to jump to the target section. In this case, however, a very long page doesn't have sections, and it should work for general-purpose scrolling, not jumping to sections.

So how can I go about implementing this method of scrolling? I'm looking for general ideas and specific implementation details. I'm also interested if an open-source implementation exists (this seems like a general-purpose problem/solution).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

遗心遗梦遗幸福 2024-10-12 21:29:20

可能有一个开源实现。我一个也不知道。也许可以向 Dropbox 开发人员发送电子邮件?

不管怎样,我这样做的方式是:

@interface UICustomisedScrollView : UISCrollView
{
    BOOL showingScroller;
    UIView scroller; //Customise this, either in IB or in viewDidLoad
}

@implementation UICustomisedScrollView

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    showingScroller = !showingScroller;
    if(showingScroller)
        scroller.hidden = NO;
    else
        scroller.hidden = YES;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if(showingScroller) {
        if(/*the touch is on the scroller*/) {
             /* scrollview.setContentOffset(...) we want to scroll according to how much the user scrolls here */
        }
        //move scroller.frame.origin to where the touch is.
    }
}

我猜这不会太难......但我还没有测试上面的代码。无论如何,这就是总体思路=)

There's probably an open source implementation for this. I don't know any. Maybe shoot an email to Dropbox developers?

Anyway, the way I'd do this is:

@interface UICustomisedScrollView : UISCrollView
{
    BOOL showingScroller;
    UIView scroller; //Customise this, either in IB or in viewDidLoad
}

@implementation UICustomisedScrollView

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    showingScroller = !showingScroller;
    if(showingScroller)
        scroller.hidden = NO;
    else
        scroller.hidden = YES;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if(showingScroller) {
        if(/*the touch is on the scroller*/) {
             /* scrollview.setContentOffset(...) we want to scroll according to how much the user scrolls here */
        }
        //move scroller.frame.origin to where the touch is.
    }
}

I'm guessing it won't be too difficult... But I haven't tested the above code yet. That's the general idea anyway =)

过潦 2024-10-12 21:29:20

尝试使用 UIPanGestureRecognizer。在您的操作中,可以使用 locationInView 来确定用户触摸的点。当状态为 UIGestureRecognizerStateBegan 且距离视图侧面足够近时执行此操作,实现快速滚动。否则,实施慢速滚动。

Try using a UIPanGestureRecognizer. In your action, can use the locationInView to determine the point the user is touching. Do this when the state is UIGestureRecognizerStateBegan and if it's close enough to the side of the view implement fast scrolling. Otherwise, implement slow scrolling.

吃素的狼 2024-10-12 21:29:19

总体思路:

我抓住了 dropbox 应用程序(非常棒)并尝试了一下。看起来 pdf 查看需要一些照片应用程序的功能,因为除了支持滚动条之外,它还会有条件地在触摸时显示半透明的导航栏和工具栏。我很确定发生的事情是他们有一个自定义视图控制器拦截触摸并做出相应的反应。

触摸时:

  1. 如果是点击,则显示/隐藏
    导航栏和工具栏。
  2. 如果它打开了
    洗涤器,开始跟踪
    触摸并滚动
    滚动视图/网络视图(无论它们是什么
    显示与)。我确信
    滚动很简单,比如
    scrollView.contentOffset =
    CGPointMake(0, (scrubber.y / [UIScreen 主屏幕].bounds.size.height) *
    滚动视图.contentSize.高度)
    。 3)
  3. 否则,将触摸传递给
    封闭视图。

PDF 显示可能还有其他隐藏的魔力(我从来没有在 cocoa touch 中做过),但有些东西告诉我这是他们的基本过程。

A general idea:

I grabbed the dropbox app (it is awesome) and played around with a bit. It looks like pdf viewing takes a bit from the photo app in that it conditionally displays a translucent navbar and toolbar on touches, in addition to supporting the scrollbar. I'm pretty sure what's going on is that they have a custom view controller intercepting touches and reacting accordingly.

On a touch:

  1. If it's a tap, show/hide the
    navbar and toolbar.
  2. If it's on
    the scrubber, begin tracking the
    touch and scrolling the
    scrollview/webview (whatever they're
    displaying with). I'm sure the
    scrolling is something simple like
    scrollView.contentOffset =
    CGPointMake(0, (scrubber.y / [UIScreen mainScreen].bounds.size.height) *
    scrollView.contentSize.height)
    . 3)
  3. Else, pass the touch on to the
    enclosed view.

There may be other hidden magic with PDF displaying (I've never done it in cocoa touch) but something tells me this is their basic process.

遮了一弯 2024-10-12 21:29:19

我不知道有任何特定于 iPhone 的解决方案,但这是 Flash 开发领域中一个古老且广为人知的话题……您可能可以从该领域提取大量伪代码。

如果您知道窗口的高度、内容的高度以及内容的当前偏移量(您知道),那么您就拥有创建自定义 UIView 所需的所有工具,该 UIView 可以用作触摸响应滑块。然后将其绘制在默认滚动条上。

I don't know of any iPhone specific solutions, but this is an old and well travelled topic in the world of Flash development... and you could probably extract a ton of pseudo code from that realm.

If you know the height of your window, and the height of your content, and the current offset of the content (which you do), then you have all the tools you need to create a custom UIView which can serve as a touch-responding slider. And then just paint it over the default scroller.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文