适用于iPhone UIView的自定义滚动条(长卷轴不吸吮)

时间:2010-12-02 18:45:27

标签: iphone objective-c uiview uiscrollview scroll

在帖子Making Long Scrolls on the iPhone Not Suck中,Aza Raskin描述了一种替代滚动条控件,它更适合在非常长的页面上使用:

Sticky Scroll Indicator

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

Dropbox iPhone应用程序(它很棒,顺便说一下!)正是这种滚动条适用于长PDF文档。通过拖动手柄上的任何位置来定期滚动;拖动手柄会将视图移动到该位置。这似乎是“从头开始”实现的,因为我认为SDK不够灵活,无法自定义现有滚动条的行为。

但是,Dropbox使用原生文档查看器在iPhone上显示文档,因此他们会以某种方式向其添加滚动条功能。看滚动条手柄?您可以拖动它以快速到达文档中的其他位置。

Dropbox scrollbar at the top Dropbox scrollbar at the bottom

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

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

4 个答案:

答案 0 :(得分:7)

一般概念:

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

触摸:

  1. 如果是点按,则显示/隐藏 导航栏和工具栏。
  2. 如果它打开了 洗涤器,开始跟踪 触摸和滚动 scrollview / webview(无论他们是什么 用...显示。我肯定的 滚动很简单 scrollView.contentOffset = CGPointMake(0, (scrubber.y / [UIScreen mainScreen].bounds.size.height) * scrollView.contentSize.height)。 3)
  3. 否则,将触摸传递给 封闭的观点。
  4. 可能还有其他隐藏的魔法与PDF显示(我从来没有在可可触摸中做过)但有些东西告诉我这是他们的基本过程。

答案 1 :(得分:4)

我不知道任何iPhone特定的解决方案,但这是Flash开发领域中一个古老而且旅行得很好的话题......你可能从该领域中提取大量的伪代码。

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

答案 2 :(得分:0)

可能有一个开源实现。我什么都不知道。也许可以向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.
    }
}

我猜它不会太难......但我还没有测试过上面的代码。无论如何,这是一般的想法=)

答案 3 :(得分:0)

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