1. 程式人生 > >uiscrollview的touch事件 以及上面子檢視touch事件 實現原理

uiscrollview的touch事件 以及上面子檢視touch事件 實現原理

我們知道當多個檢視進行疊加的時候,touch事件是作用到最上面的檢視上,但是如果父檢視是UIScrollView,如果預設,可能touch子檢視會造成UIScrollView的滾動。

UIScrollView滾動的原因,可以看UIScrollView 原理

我在這裡簡單的描述一下,UIScrollView的工作原理,當手指touch的時候,UIScrollView會攔截Event,會等待一段時間,在這段時間內,如果沒有手指沒有移動,當時間結束時,UIScrollView會發送tracking events到子檢視上。在時間結束前,手指發生了移動,那麼UIScrollView就會進行移動,從而取笑傳送tracking。

那麼,UIScrollView的子類想要接受touch事件,就是使用者點選UIScrollView上的檢視時,要先處理檢視上的touch,而不發生滾動。這時候就需要UIScrollView的子類過載touchesShouldBegin:withEvent:inContentView: ,從而決定自己是否接受子檢視中的touch事件。

上面都是理論的知識,下面看一個簡單的例子:

外面紅色是一個UIScrollView,黃色是在UIScrollView上新增的UIView。最後的效果是,當在黃色區域內touch時,touch事件會作用到UIView上,當touch紅色區域時,整個檢視上下滾動。下面是實現的過程。

一、建立工程,然後建立myScrollView,並且myScrollView繼承自UIScrollView。

#import <UIKit/UIKit.h>

   

@interface myScrollView : UIScrollView { 
}

   

@end

具體的實現:

#import "myScrollView.h"

   

#import "MyView.h"

   

@implementation myScrollView

   

- (id)initWithFrame:(CGRect)frame 

    self = [super initWithFrame:frame]; 
    if (self) { 
        [self setBackgroundColor:[UIColor redColor]]; 
        
        MyView *myView=[[MyView alloc] initWithFrame:CGRectMake(1, 3, 100, 200)]; 
        [self addSubview:myView]; 
        [myView release]; 
    } 
    return self; 
}

   

- (void)dealloc 

    [super dealloc]; 
}

   

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view 

    NSLog(@"使用者點選了scroll上的檢視%@,是否開始滾動scroll",view); 
    //返回yes 是不滾動 scroll 返回no 是滾動scroll 
    return YES; 

- (BOOL)touchesShouldCancelInContentView:(UIView *)view 

  
    NSLog(@"使用者點選的檢視 %@",view); 
   
    //NO scroll不可以滾動 YES scroll可以滾動 
    return NO; 

@end

重寫了- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view方法和- (BOOL)touchesShouldCancelInContentView:(UIView *)view方法。

其中(BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view,是使用者點選黃色區域內,先觸發這個方法,當返回YES時,touch事件作用到黃色檢視上,當返回no時,紅色可以上下滾動。

(BOOL)touchesShouldCancelInContentView:(UIView *)view是傳送tracking前,先作用這個方法。

下面是點選黃的區域的日誌:

2011-06-02 10:19:42.469 scrollTouch[38255:207] 使用者點選了scroll上的檢視<MyView: 0x4e26f90; frame = (1 3; 100 200); layer = <CALayer: 0x4e270a0>>,是否開始滾動scroll 
2011-06-02 10:19:42.658 scrollTouch[38255:207] 使用者點選的檢視 <MyView: 0x4e26f90; frame = (1 3; 100 200); layer = <CALayer: 0x4e270a0>>

二、新增mySrollView到根檢視上:

- (void)viewDidLoad 

    [super viewDidLoad]; 

    myScrollView *view=[[myScrollView alloc] initWithFrame:CGRectMake(10, 9, 300, 400)]; 
    [view setUserInteractionEnabled:YES]; 
    [view setScrollEnabled:YES]; 

//NO 傳送滾動的通知 但是就算手指移動 scroll也不會動了 YES 傳送通知 scroll可以移動 
    [view setCanCancelContentTouches:YES]; 
    [view setBounces:NO]; 
    // NO 立即通知touchesShouldBegin:withEvent:inContentView 看是否滾動 scroll 
    [view setDelaysContentTouches:NO]; // 這句是關鍵,預設為YES,不設為NO則touchesShouldBegin:withEvent:inContentView:可能不被回撥
    [view setContentSize:CGSizeMake(300, 900)]; 
    [self.view addSubview:view]; 
    [view release]; 
}

三、MyView檢視的實現。

#import "MyView.h"

   

@implementation MyView

   

- (id)initWithFrame:(CGRect)frame 

    self = [super initWithFrame:frame]; 
    if (self) { 
        [self setBackgroundColor:[UIColor yellowColor]]; 
    } 
    return self; 
}

   

- (void)dealloc 

    [super dealloc]; 
}

   

@end

通過監聽手指點選的位置來判斷點選的是哪一個scrollview來進行處理

首先自定義一個scrollview在裡面過載以下方法

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
    // 獲取一個UITouch
    UITouch *touch = [touches anyObject];
    // 獲取當前的位置
    CGPoint current = [touch locationInView:self];
    CGFloat y = 280;
    if (current.y >= y+ 10) {
        //在地圖上
        NSLog(@"滾動地圖");
        return YES;
    } else {
        return [super touchesShouldBegin:touches withEvent:event inContentView:view];
    }
}

touchesShouldCancelInContentView從字面理解大概意思為 應該取消當前檢視的觸控事件
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
    if ([view isKindOfClass:NSClassFromString(@"TapDetectingView")]) {

//在地圖上返回NO
        return NO;
    } else {
        return [super touchesShouldCancelInContentView:view];
    }
}
self.delaysContentTouches = NO;

當手指放到UIScrollview上時,uiscrollview會等待一個時間段才去響應觸控事件,這個屬性關閉後無論手指移動的多麼快都可以直接響應事件



相關推薦

uiscrollview的touch事件 以及面子檢視touch事件 實現原理

我們知道當多個檢視進行疊加的時候,touch事件是作用到最上面的檢視上,但是如果父檢視是UIScrollView,如果預設,可能touch子檢視會造成UIScrollView的滾動。 UIScrollView滾動的原因,可以看UIScrollView 原理。 我在這裡

淺談BloomFilter【】基本概念和實現原理

pty 是否 的人 它的 構建 網絡爬蟲 ace head filters ? ??在日常生活中。包括在設計計算機軟件時,我們常常要推斷一個元素是否在一個集合中。

java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一彙總 Spring中AOP的兩種代理方式(Java動態代理和CGLIB代理)

若代理類在程式執行前就已經存在,那麼這種代理方式被成為 靜態代理 ,這種情況下的代理類通常都是我們在Java程式碼中定義的。 通常情況下, 靜態代理中的代理類和委託類會實現同一介面或是派生自相同的父類。 一、概述1. 什麼是代理我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委託”代理為

Spring裡的aop實現方式和原始碼分析 java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一彙總

使用"橫切"技術,AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事務。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

Mybatis(四):MyBatis核心元件介紹原理解析和原始碼解讀 java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一彙總

Mybatis核心成員 Configuration        MyBatis所有的配置資訊都儲存在Configuration物件之中,配置檔案中的大部分配置都會儲存到該類中 SqlSession         &

php後臺運行以及定時任務的4種實現原理以及代碼

html 除了 tar 時間比較 文章 limit 代碼 最好 程序員 後臺任務在我們php編程中雖然用的不是很多甚至很多php程序員都沒聽過甚至覺得後臺運行是不可能實現的,本人因為項目需求多次演變在這裏分享給大家,本人第一次想實現後臺運行是利用 方法二 在其執行完成後輸出

Android檢視SurfaceView的實現原理分析

        在Android系統中,有一種特殊的檢視,稱為SurfaceView,它擁有獨立的繪圖表面,即它不與其宿主視窗共享同一個繪圖表面。由於擁有獨立的繪圖表面,因此SurfaceView的UI就可以在一個獨立的執行緒中進行繪製。又由於不會佔用主執行緒資源,Surfa

【轉載】移動端touch事件影響click事件以及在touchmove新增preventDefault導致頁面無法滾動的解決方法

原文地址:連結這兩天自己在寫一個手機網頁,用到了觸屏滑動的特效,就是往右滑動的時候左側隱藏的選單從左邊劃出來。做完之後在手機原生瀏覽器中執行正常,但在QQ和微信中開啟,發現touchmove只會觸發一次,而且touchend也經常不觸發。之後百度了一下這個問題,原因是主要是由

UIScrollView的作用原理實現scrollView中touch事件作用子檢視

我們知道當多個檢視進行疊加的時候,touch事件是作用到最上面的檢視上,但是如果父檢視是UIScrollView,如果預設,可能touch子檢視會造成UIScrollView的滾動。 UIScrollView滾動的原因,可以看UIScrollView 原理。 我在這裡

jQuery檢視dom元素繫結的事件列表

作為技術狂熱分子的職業本能,看到一個技術產品的功能,總會忍不住想知道它是怎麼被實現的。比如我每每看到別人網站一個很炫的介面或者很酷的功能,就忍不住打開了瀏覽器的控制檯。。。 好,不扯遠,說說當你想看到網站上某個元素繫結的事件函式的程式碼時應該怎麼做吧。 檢視原生

實現移動端touch事件的橫向滑動列表效果

parseint 滑動 borde lec let doc kit order mov 要實現手機端橫向滑動效果並不難,了解實現的原理及業務邏輯就很容易實現。原理:touchstart(手指按下瞬間獲取相對於頁面的位置)——》touchmove(手指移動多少,元素相應移動多

position布局影響點擊事件以及冒泡獲取事件目標

  在編寫功能時總是會出現很多意想不到的問題,現在就講講證券通投顧網遇到的兩個問題,通過舉一個相似的例子來解說。 &lt;1&gt;元素互相獨立,不存在包含於被包含 選擇城市的按鈕,為它綁定點擊事件,點擊後就彈出城市列表層,城市列表層設置了position與z-index的值來進行

鼠標移與移出事件

() func on() fun cti ide popd hover none $(‘#newcl‘).hover(function(){ $("#newcl").hide(); $("#po

移動端開發用touch事件還是click事件

device 問題 桌面網站 有意義 用戶 雨後春筍 phone 平臺 系統 前端開發現在包含了跨瀏覽器,跨平臺(不同操作系統)和跨設備(不同尺寸的設備)開發。 在移動開發的過程中,到底選取touch事件還是click事件?對了,請不要鄙視click,click在移動端開發

移動WEB開發之JS內置touch事件[轉]

調用 位置 .com 構造 turn listener 附件 cli 瀏覽器 iOS上的Safari也支持click 和mouseover等傳統的交互事件,只是不推薦在iOS的瀏覽器應用上使用click和mouseover,因為這兩個事件是為了支持鼠標點擊而設計 出來的。

移動端筆記——jQuery touch事件

star sed 支持 event eve spc 觀察 log 普通 判斷移動端還是pc端function IsPC() { var userAgentInfo = navigator.userAgent; var Age

拉加載事件

解析 con 操作 bsp ajax ons scrolltop dom 器) //上拉加載更多 $(window).on("scroll",function() { var scrollTop = $(this).scrollTop(); v

jQuery -- touch事件之滑動判斷(左右上下方向)

ble art func nat tde span class csdn def $("body").on("touchstart", function(e) { // 判斷默認行為是否可以被禁用 if (e.cancelable) { /

cocos creator Touch事件應用(觸控選擇多個子節點)

event false 等待 結果 ble cte mask convert 計算 最近參與了cocos creator的研究,開發小遊戲,結果被一個事件坑得不行不行的。現在終於解決了,分享給大家。 原理 1.觸控事件是針對節點的 2.觸控事件的冒泡,是直接關系冒泡,父

JS基礎--函數與BOM、DOM操作、JS中的事件以及內置對象

對話框 回車 == 問題 tde tle ets fixed 訪問 前 言 絮叨絮叨 這裏是JS基礎知識集中講解的第三篇,也是最後一篇,三篇JS的基礎,大多是知識的羅列,並沒有涉及更難得東西,幹貨滿滿!看完這一篇後,相信許多正在像我一樣正處於初