UIScrollView的作用原理,实现scrollView传递touch事件给子视图

2023-05-16

我们知道当多个视图进行叠加的时候,touch事件是作用到最上面的视图上,但是如果父视图是UIScrollView,如果默认,可能touch子视图会造成UIScrollView的滚动。

UIScrollView滚动的原因,可以看UIScrollView 原理。

我在这里简单的描述一下,UIScrollView的工作原理,当手指touch的时候,UIScrollView会拦截Event,会等待一段时间,在这段时间内,如果没有手指没有移动,当时间结束时,UIScrollView会发送tracking events到子视图上。在时间结束前,手指发生了移动,那么UIScrollView就会进行移动,从而取笑发送tracking。

 

那么,UIScrollView的子类想要接受touch事件,就是用户点击UIScrollView上的视图时,要先处理视图上的touch,而不发生滚动。这时候就需要UIScrollView的子类重载touchesShouldBegin:withEvent:inContentView: ,从而决定自己是否接受子视图中的touch事件。

上面都是理论的知识,下面看一个简单的例子:

image

外面红色是一个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) {
        // Initialization code
        [self setBackgroundColor:[UIColor redColor]];
        
        myView * aView = [[myView alloc] initWithFrame:CGRectMake(1, 3, 100, 200)];
        [self addSubview:aView];
        [aView release];
    }
    return self;
}

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    NSLog(@"用户触摸了scroll上的视图%@,是否开始滚动scroll", view);
    //返回yes - 将触摸事件传递给相应的subView; 返回no - 直接滚动scrollView,不传递触摸事件到subView
    return YES// NO;
}

- (BOOL)touchesShouldCancelInContentView:(UIView *)view{
    NSLog(@"scrollView取消传递触摸事件到视图%@", view);    
    //no - 不取消,touch事件由view处理,scrollView不滚动; yes - scrollView取消,touch事件由scrollView处理,可滚动
    return YES// NO;
}

@end

重写了方法

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

- (BOOL)touchesShouldCancelInContentView:(UIView *)view。


(BOOL)touchesShouldBegin:withEvent:inContentView:

用户点击黄色区域时,先触发这个方法。

当返回YES时,touch事件作用到黄色视图上;

当返回no时,touch事件不传递到黄色视图,红色视图马上滚动(当然前提是scrollView的scrollEnabled字段为YES)。


(BOOL)touchesShouldCancelInContentView:

只有scrollView的canCancelContentTouches字段为YES 且 (BOOL)touchesShouldBegin:withEvent:inContentView:返回YES时,这个方法才会被调用。

调用前,由于(BOOL)touchesShouldBegin:withEvent:inContentView:返回YES,scrollView上对应的view会接收到touch事件,因此方法(BOOL)touchesShouldCancelInContentView:被调用前,view可以已经触发了touchesBegan:withEvent:方法甚至是touchesMoved:withEvent:方法,至于view最后会调用touchesEnden:withEvent:还是touchesCanceled:withEvent:取决于(BOOL)touchesShouldCancelInContentView:的返回值

scrollView发送tracking前,调用这个方法。

返回YES时,若scrollView的canCancelContentTouches字段为YES,view会马上调用touchesCanceled:withEvent:,scrollView进行tracking以滚动。

返回NO时,scrollView不进行tracking,也不滚动,touch事件交由view处理。


二、添加mySrollView到根视图上

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.    
    [self layoutCstmView];
}

- (void)layoutCstmView
{
    myScrollView * scrollView = [[myScrollView alloc] initWithFrame:CGRectMake(10, 9, 300, 400)];
    [scrollView setUserInteractionEnabled:YES];
    [scrollView setScrollEnabled:YES];
    
    //NO - 设置scrollView不能取消传递touch事件,此时就算手指若在subView上滑动,scrollView不滚动; YES - 设置scrollView可取消传递touch事件
    [scrollView setCanCancelContentTouches:YES];
    [scrollView setBounces:NO];
    
    //NO - 立即通知touchesShouldBegin:withEvent:inContentView
    [scrollView setDelaysContentTouches:NO];
    [scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, 900)];
    
    [self.view addSubview:scrollView];
    [scrollView release];
}

三、MyView视图的实现

#import "myView.h"

@implementation myView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.backgroundColor = [UIColor yellowColor];
    }
    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    printf("myView touchesBegan \n");
    self.backgroundColor = [UIColor grayColor];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    printf("myView touchesMoved \n");
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    printf("myView touchesEnded \n");
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    printf("myView touchesCancelled \n");
    self.backgroundColor = [UIColor yellowColor];
}
   
@end






本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIScrollView的作用原理,实现scrollView传递touch事件给子视图 的相关文章

  • iPhone SDK:拖动 UIImageView 时出现问题

    我正在尝试在我的应用程序中拖动 iPhone 屏幕上的 UIImageView 目前我设置的拖动功能很好 拖动图像确实会在屏幕上移动它 问题是你不必拖动图像视图来移动它 你也可以拖动屏幕上的任何地方 它会移动图像 我是这个平台的新手 所以我
  • 当自定义子视图处理触摸时防止 UITableView 滚动

    在我的 iOS 应用程序中 有一个 UITableView 其中一个单元格中包含一个自定义子视图 该单元格是一个交互式视图 它处理触摸事件 touchesBegan touchesEnded touchesMoved 以更新自身 问题是 当
  • 是否可以使用UIPageControl来控制UITableView的移动?

    从Apple示例 PageControl 中我们可以知道UIPageControl可以用来控制scrollview中页面的移动 由于 UITableView 是 UIScrollView 的子类 我想使用 UIPageControl 来控制
  • 确定视图是否在屏幕上 - Android

    我对这个有点困惑 首先也是最重要的是 以下链接很有用 但是我提出了一些可见性问题 链接 检查视图可见性 https stackoverflow com questions 4628800 android how to check if a
  • 在文本视图滚动之前无法看到 UITextView 中的文本

    我的应用程序中有一堆文本视图 由于某种原因 无论我以编程方式 来自互联网 还是通过界面生成器 硬编码 设置 UITextView 文本 无论我做什么 当我在测试时转到该文本视图时它都是空白的 但当我滚动它的那一刻 所有文本就突然出现了 只是
  • iOS 滚动视图允许滚动过去的内容

    我正在努力优化我的应用程序以适应横向和较小的屏幕 我主要使用滚动视图来实现这一点 在我的其中一个视图中 我有一个容器视图 当我在故事板中的设备之间切换时 这个容器视图看起来很完美 容器视图映射到具有滚动视图的视图控制器 该滚动视图的顶部 底
  • 自上次触摸起 60 秒后开始 ViewFlipper 翻转

    我的应用程序包含一个ViewFlipper与一些图像 当应用程序启动时 ViewFlipper startflipping 当用户触摸屏幕时ViewFlipper stopflipping 我必须在上次触摸后 60 秒后执行此操作 View
  • 每次 UIScrollView 释放时都会发生内存泄漏

    在我的应用程序中 我有一个滚动视图和四个表格视图 每次拖动然后释放时 我都会泄漏 48 字节 这确实很重要 正如您所看到的 两组泄漏都有相同的来源 有人见过这样的泄漏吗 Edit 1 当我单击泄漏旁边的箭头时 我会得到泄漏的以下信息 您所看
  • UIScrollView 总是弹回来

    我将一堆对象放入 UIScrollView 中 没有任何问题 当我尝试 滚动 到某些屏幕外对象时 只要我在拖动手指后按住手指 它们就会出现 但是当我让你 UIScrollView 弹回到原始位置 有办法防止这种情况吗 顺便说一句 当发生这种
  • 可接受的滚动 FPS 是多少?提高性能的技巧有哪些?

    我在许多 WWDC 视频中看到 您希望尽可能达到 60 0 FPS 以获得更好的平滑滚动体验 我有一个 UIScrollLView 它可以立即加载图像和几个表格视图 目前我的帧速率为 30 FPS 这是推荐 FPS 的一半 只是想知道对于加
  • 捕获多点触摸屏上的双击触摸

    我发布了另一个问题 如何通过监视 TouchDown 事件的触摸之间的时间跨度来 手动 捕获双击 但它有很多问题 有谁知道在多点触摸屏上捕获双击的标准 Microsoft 方式 事件 多谢 Dan 我检查了点击位置和秒表的组合 效果非常完美
  • Horizo​​ntalScrollView 将 GridView 缩小为小行

    当我将 Horizo ntalScrollView 放在 GridView 周围时 GridView 会被压缩到左侧的一个小列中 Gridview 的垂直滚动条甚至出现在左侧 Horizo ntalScrollView 的宽度设置为 fil
  • 移动物体而不实际接触物体

    我是 iPhone 开发的初学者 我一直在寻找这个问题的答案 但还没有找到任何东西 我想做的是允许用户移动对象而无需实际触摸该对象 他们可以触摸屏幕上的任何位置 并且当他们移动时 对象将从原来的位置向用户的方向移动移动但不会跳到他们的触摸位
  • 如何检测 Android 上的触摸输入

    现在我想做的就是检测何时按下屏幕 然后显示一条日志消息以确认它发生了 到目前为止 我的代码是根据 CameraPreview 示例代码修改的 它最终会拍摄一张照片 因此大部分代码位于扩展 SurfaceView 的类中 SDK 中示例代码的
  • 消除 Android 网络应用程序的 onclick 延迟

    你好 我正在构建一个网络应用程序 为了消除 onclick 延迟 我发现了这个脚本http cubiq org remove onclick delay on webkit for iphone http cubiq org remove
  • UIButton 不响应 UITableViewCell 中的单击事件

    ios 中有一个黑暗巫术阻止我的按钮被点击 如果我不向 uitableviewcell 添加按钮 并且单击该按钮 则会触发该事件 但如果按钮在 uitableviewcell 中 它不会被触发 看起来表 我已经准备好了示例代码 如果你们可以
  • 如何使用 UIScrollView?

    我该如何使用UIScrollView 请给我一个带有一张滚动图像的简单示例 这将使您深入了解UIScrollView控制 学习 UIScrollView 的基础知识 https stackoverflow com questions 159
  • 以编程方式在 UIView 中添加 UIScrollView

    我有一个问题如何在UIView中添加UIScrollView 以便UIScrollView能够正常工作 UIScrollView scroll UIScrollView alloc initWithFrame CGRectMake 0 0
  • 缩放网页内容上的特定元素(HTML、CSS、JavaScript)

    如果用户在移动设备上缩放网站 我只想缩放网站的特定元素 某个 div 下图展示了我的想法 如您所见 测试已缩放 但顶部 div 保持相同大小 仅包含 test 的 div 被缩放 缩放 有人可以给我一些关于如何实现这一目标的提示吗 我真的不
  • UIScrollView setZoomScale 将应用的旋转设置回零

    我已经从事地图替换工作很长一段时间了 整个事情的工作原理是UIScrollView由一个支持CATiledLayer 为了旋转我的地图 我旋转图层本身 使用CATransform3DMakeRotation 到目前为止效果很好 但如果我打电

随机推荐