pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

如何準確知道 UIScrollView 的滾動何時停止?

How to know exactly when a UIScrollView#39;s scrolling has stopped?(如何準確知道 UIScrollView 的滾動何時停止?)
本文介紹了如何準確知道 UIScrollView 的滾動何時停止?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

簡而言之,我需要確切地知道滾動視圖何時停止滾動.我所說的停止滾動"是指它不再移動且不再被觸摸的那一刻.

In short, I need to know exactly when the scrollview stopped scrolling. By 'stopped scrolling', I mean the moment at which it is no longer moving and not being touched.

我一直在研究一個帶有選擇選項卡的水平 UIScrollView 子類(適用于 iOS 4).它的要求之一是它在低于一定速度時停止滾動,以允許用戶更快地交互.它還應該捕捉到選項卡的開頭.換句話說,當用戶釋放滾動視圖并且它的速度很低時,它會捕捉到一個位置.我已經實現了這個并且它可以工作,但是它有一個錯誤.

I've been working on a horizontal UIScrollView subclass (for iOS 4) with selection tabs in it. One of its requirements is that it stops scrolling below a certain speed to allow user interaction more quickly. It should also snap to the start of a tab. In other words, when the user releases the scrollview and its speed is low, it snaps to a position. I've implemented this and it works, but there's a bug in it.

我現在擁有的:

滾動視圖是它自己的委托.在每次調用 scrollViewDidScroll: 時,它都會刷新與速度相關的變量:

The scrollview is its own delegate. at every call to scrollViewDidScroll:, it refreshes its speed-related variables:

-(void)refreshCurrentSpeed
{
    float currentOffset = self.contentOffset.x;
    NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];

    deltaOffset = (currentOffset - prevOffset);
    deltaTime = (currentTime - prevTime);    
    currentSpeed = deltaOffset/deltaTime;
    prevOffset = currentOffset;
    prevTime = currentTime;

    NSLog(@"deltaOffset is now %f, deltaTime is now %f and speed is %f",deltaOffset,deltaTime,currentSpeed);
}

然后根據需要繼續捕捉:

Then proceeds to snap if needed:

-(void)snapIfNeeded
{
    if(canStopScrolling && currentSpeed <70.0f && currentSpeed>-70.0f)
    {
        NSLog(@"Stopping with a speed of %f points per second", currentSpeed);
        [self stopMoving];

        float scrollDistancePastTabStart = fmodf(self.contentOffset.x, (self.frame.size.width/3));
        float scrollSnapX = self.contentOffset.x - scrollDistancePastTabStart;
        if(scrollDistancePastTabStart > self.frame.size.width/6)
        {
            scrollSnapX += self.frame.size.width/3;
        }
        float maxSnapX = self.contentSize.width-self.frame.size.width;
        if(scrollSnapX>maxSnapX)
        {
            scrollSnapX = maxSnapX;
        }
        [UIView animateWithDuration:0.3
                         animations:^{self.contentOffset=CGPointMake(scrollSnapX, self.contentOffset.y);}
                         completion:^(BOOL finished){[self stopMoving];}
        ];
    }
    else
    {
        NSLog(@"Did not stop with a speed of %f points per second", currentSpeed);
    }
}

-(void)stopMoving
{
    if(self.dragging)
    {
        [self setContentOffset:CGPointMake(self.contentOffset.x, self.contentOffset.y) animated:NO];
    }
    canStopScrolling = NO;
}

這里是委托方法:

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    canStopScrolling = NO;
    [self refreshCurrentSpeed];
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    canStopScrolling = YES;
    NSLog(@"Did end dragging");
    [self snapIfNeeded];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self refreshCurrentSpeed];
    [self snapIfNeeded];
}

這在大多數情況下都很有效,除了以下兩種情況:1.當用戶在不松開手指的情況下滾動并在移動后立即在接近靜止的時間松開時,它通常會按預期的位置捕捉??到它應該的位置,但很多時候不會.通常需要幾次嘗試才能實現.時間(非常低)和/或距離(相當高)的奇數值出現在發布時,導致高速值,而實際上滾動視圖幾乎或完全靜止.2. 當用戶點擊滾動視圖停止其移動時,滾動視圖似乎將 contentOffset 設置為之前的位置.這種瞬移導致非常高的速度值.這可以通過檢查之前的增量是否為 currentDelta*-1 來解決,但我更喜歡更穩定的解決方案.

This works well most of the time, except in two scenarios: 1. When the user scrolls without releasing his/her finger and lets go at a near stationary timing right after moving, it often snaps to its position as it's supposed to, but a lot of times, does not. It usually takes a few attempts to get it to happen. Odd values for time (very low) and/or distance (rather high) appear at the release, causing a high speed value while the scrollView is, in reality, nearly or entirely stationary. 2. When the user taps the scrollview to stop its movement, it seems the scrollview sets the contentOffset to its previous spot. This teleportation results in a very high speed value. This could be fixed by checking if the previous delta is currentDelta*-1, but I'd prefer a more stable solution.

我嘗試過使用 didEndDecelerating,但是當故障發生時,它不會被調用.這可能證實它已經是靜止的.當滾動視圖完全停止移動時,似乎沒有調用委托方法.

I've tried using didEndDecelerating, but when the glitch occurs, it does not get called. This probably confirms that it's stationary already. There seems to be no delegate method that gets called when the scrollview stopped moving completely.

如果您想親自查看故障,這里有一些代碼可以用標簽填充滾動視圖:

If you'd like to see the glitch yourself, here's some code to fill the scrollview with tabs:

@interface  UIScrollView <UIScrollViewDelegate>
{
    bool canStopScrolling;
    float prevOffset;
    float deltaOffset; //remembered for debug purposes
    NSTimeInterval prevTime;
    NSTimeInterval deltaTime; //remembered for debug purposes
    float currentSpeed;
}

-(void)stopMoving;
-(void)snapIfNeeded;
-(void)refreshCurrentSpeed;

@end


@implementation TabScrollView

-(id) init
{
    self = [super init];
    if(self)
    {
        self.delegate = self;
        self.frame = CGRectMake(0.0f,0.0f,320.0f,40.0f);
        self.backgroundColor = [UIColor grayColor];
        float tabWidth = self.frame.size.width/3;
        self.contentSize = CGSizeMake(100*tabWidth, 40.0f);
        for(int i=0; i<100;i++)
        {
            UIView *view = [[UIView alloc] init];
            view.frame = CGRectMake(i*tabWidth,0.0f,tabWidth,40.0f);
            view.backgroundColor = [UIColor colorWithWhite:(float)(i%2) alpha:1.0f];
            [self addSubview:view];
        }
    }
    return self;
}

@end

這個問題的簡短版本:如何知道滾動視圖何時停止滾動?didEndDecelerating: 當你靜止釋放它時不會被調用,didEndDragging: 在滾動過程中發生了很多,并且檢查速度是不可靠的,因為這種奇怪的跳躍"會設置速度到隨機的東西.

A shorter version of this question: how to know when the scrollview stopped scrolling? didEndDecelerating: does not get called when you release it stationary, didEndDragging: happens a lot during the scrolling and checking for speed is unreliable due to this odd 'jump' which sets the speed to something random.

推薦答案

我找到了解決方案:

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

我之前沒有注意到最后一點,willDecelerate.結束觸摸時滾動視圖靜止時為假.結合上面提到的速度檢查,我可以在它很慢(并且沒有被觸摸)或靜止時捕捉它.

I did not notice that last bit before, willDecelerate. It is false when the scrollView is stationary when ending the touch. Combined with the above-mentioned speed check, I can snap both when it's slow (and not being touched) or when it's stationary.

對于沒有進行任何捕捉但需要知道何時停止滾動的任何人,didEndDecelerating 將在滾動運動結束時調用.結合對 didEndDragging 中的 willDecelerate 的檢查,您將知道滾動何時停止.

For anyone not doing any snapping but needs to know when scrolling stopped, didEndDecelerating will be called at the end of the scroll movement. Combined with a check on willDecelerate in didEndDragging, you'll know when the scrolling has stopped.

這篇關于如何準確知道 UIScrollView 的滾動何時停止?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How to subclass UIScrollView and make the delegate property private(如何繼承 UIScrollView 并使委托屬性私有)
Swift - how to get last taken 3 photos from photo library?(Swift - 如何從照片庫中獲取最后拍攝的 3 張照片?)
Setting contentOffset programmatically triggers scrollViewDidScroll(以編程方式設置 contentOffset 觸發 scrollViewDidScroll)
Photos app-like gap between pages in UIScrollView with pagingEnabled(使用 pagingEnabled 的 UIScrollView 中頁面之間的照片應用程序式間隙)
why UIScrollView is leaving space from top in ios 6 and ios 7(為什么 UIScrollView 在 ios 6 和 ios 7 中從頂部留下空間)
UIScrollView pauses NSTimer while scrolling(UIScrollView 在滾動時暫停 NSTimer)
主站蜘蛛池模板: 广东高华家具-公寓床|学生宿舍双层铁床厂家【质保十年】 | 上海软件开发-上海软件公司-软件外包-企业软件定制开发公司-咏熠科技 | 合肥网络推广_合肥SEO网站优化-安徽沃龙First| 水厂自动化-水厂控制系统-泵站自动化|控制系统-闸门自动化控制-济南华通中控科技有限公司 | 网站建设,北京网站建设,北京网站建设公司,网站系统开发,北京网站制作公司,响应式网站,做网站公司,海淀做网站,朝阳做网站,昌平做网站,建站公司 | 广州番禺搬家公司_天河黄埔搬家公司_企业工厂搬迁_日式搬家_广州搬家公司_厚道搬迁搬家公司 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 污水处理设备维修_污水处理工程改造_机械格栅_过滤设备_气浮设备_刮吸泥机_污泥浓缩罐_污水处理设备_污水处理工程-北京龙泉新禹科技有限公司 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | 今日热点_实时热点_奇闻异事_趣闻趣事_灵异事件 - 奇闻事件 | 换链神器官网-友情链接交换、购买交易于一体的站长平台 | GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | 网站建设-高端品牌网站设计制作一站式定制_杭州APP/微信小程序开发运营-鼎易科技 | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 一体化污水处理设备,一体化污水设备厂家-宜兴市福源水处理设备有限公司 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 | 船用泵,船用离心泵,船用喷射泵,泰州隆华船舶设备有限公司 | 通风气楼_通风天窗_屋顶风机-山东美创通风设备有限公司 | 金属软管_不锈钢金属软管_巩义市润达管道设备制造有限公司 | 噪声治理公司-噪音治理专业隔音降噪公司 | 报警器_家用防盗报警器_烟雾报警器_燃气报警器_防盗报警系统厂家-深圳市刻锐智能科技有限公司 | 单机除尘器 骨架-脉冲除尘器设备生产厂家-润天环保设备 | 底部填充胶_电子封装胶_芯片封装胶_芯片底部填充胶厂家-东莞汉思新材料 | 皮带机-带式输送机价格-固定式胶带机生产厂家-河南坤威机械 | 发电机价格|发电机组价格|柴油发电机价格|柴油发电机组价格网 | 叉车电池-叉车电瓶-叉车蓄电池-铅酸蓄电池-电动叉车蓄电池生产厂家 | 制氮设备-变压吸附制氮设备-制氧设备-杭州聚贤气体设备制造有限公司 | 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 重庆钣金加工厂家首页-专业定做监控电视墙_操作台 | 蒸压釜_蒸养釜_蒸压釜厂家-山东鑫泰鑫智能装备有限公司 | 飞行者联盟-飞机模拟机_无人机_低空经济_航空技术交流平台 | 东莞动力锂电池保护板_BMS智能软件保护板_锂电池主动均衡保护板-东莞市倡芯电子科技有限公司 | 恒温恒湿箱(药品/保健品/食品/半导体/细菌)-兰贝石(北京)科技有限公司 | 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 彩信群发_群发彩信软件_视频短信营销平台-达信通| 微型实验室真空泵-无油干式真空泵-微型涡旋耐腐蚀压缩机-思科涡旋科技(杭州)有限公司 | 防水套管|柔性防水套管|伸缩器|伸缩接头|传力接头-河南伟创管道 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | 出国劳务公司_正规派遣公司[严海]| 整合营销推广|营销网络推广公司|石家庄网站优化推广公司|智营销 好物生环保网、环保论坛 - 环保人的学习交流平台 | 衬氟旋塞阀-卡套旋塞阀-中升阀门首页|