网上科普有关“从用户点击屏幕到程序作出反应之间都发生了什么?”话题很是火热,小编也是针对从用户点击屏幕到程序作出反应之间都发生了什么?寻找了一些与之相关的一些信息进行分析 ,如果能碰巧解决你现在面临的问题,希望能够帮助到您。
如今我们但凡看到一块屏幕我们都会忍不住去点击,几乎每一块屏幕都能多点触控 。我们用多点触控屏幕是那么自然 ,就像生来就有的技巧。那么在我们手指触碰屏幕的一瞬间,到底发生了什么呢?首先我们需要先了解事件类型。
当我们操作手机时,一般有触摸屏幕、摇晃手机、远程遥控三种方式 ,分别对应的事件类型是:
1. ?触摸事件 (Multitouch events)
2. 运动事件 ?(Accelerometer events)
3. 远程控制 ?(Remote control events)
当这些事件发生时,iOS会生成对应的响应链, 来查找第一响应对象并进行事件的分发 ,最后处理事件,完成相应操作 。下面我们接着看关于响应链的概念。
响应链,顾名思义 ,就是有一系列响应对象的集合成的一个层次结构。那什么又是响应对象呢?Cocoa里面规定:凡是继承于UIResponder或者UIResponder的子类的对象都可以作为 响应对象 ,比如UIApplication 、UIViewController和UIView 。
在响应用户触摸等事件中,APP具体会通过下面三步来完成操作:
1. ? 生成事件 。当用户点击屏幕时,会产生一个触摸事件 ,并放入由Application管理的事件队列中,然后在队列中取出最前面的事件交给Window处理。
2. ? 查找第一响应对象 。Window收到事件后会在视图层次结构中找到最适合的一个视图来处理事件,通常一个窗口中最适合处理当前事件的对象称为第一响应对象。
3. ? 处理事件 。通常最后是第一响应对象处理事件 ,如果第一响应对象无法处理事件,就会把事件传递给下一个响应对象,直到Application 。如果Application也无法处理 ,那就丢弃掉此事件。
在上述系列操作中,所参与到的UIApplication、UIViewController和UIView就作为响应对象构成这次事件的 响应链 。
当Window收到事件后,会用一种类似二分法的方式来查找第一响应对象 ,通常就是用户点击处最上层的一个View。
Window实例对象会首先在它的内容视图上调用hitTest:withEvent:,此方法会在其视图层级结构中的每个视图上调用pointInside:withEvent:(该方法用来判断点击事件发生的位置是否处于当前视图范围内,以确定用户是不是点击了当前视图) ,如果pointInside:withEvent:返回true,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是要找的hit-test view 。
hitTest:withEvent:方法的处理流程如下:
首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内 ,若返回false,则对应hitTest:withEvent:返回nil; 若返回true, 则向当前视图的所有子视图发送hitTest:withEvent:消息,直到有子视图返回非空对象或者全部子视图遍历完毕;若最后一层某个子视图pointInside:withEvent:方法返回true ,则对应hitTest:withEvent:方法返回此对象,直到把此对象依次向上返回到Application则处理结束。
我们结合一个实例来加深理解:
假设View A 是Window的根视图,用户点了View E之后:
1. Window首先会对View A进行 hit-test ,具体表现为View A调用hitTest:withEvent:,而此方法进而会调用pointInside:withEvent:方法,显然返回true ,并对View A所有的子视图(View B,View C)进行hit-test;
2. View B调用pointInside:withEvent:方法,返回false ,对应hitTest:withEvent:返回nil;
3. View C调用pointInside:withEvent:方法,返回true,则对View C所有的子视图(View D,View E)进行hit-test;
4. View D调用pointInside:withEvent:方法 ,返回false,对应hitTest:withEvent:返回nil;
5. View E调用pointInside:withEvent:方法,返回true ,而且View E没有子视图了,则hitTest:withEvent:返回View E,再往回溯 ,View C对应hitTest:withEvent:也返回View E,View A也返回View E,这样Application就知道了View E是第一响应对象。
当Application就知道了第一响应对象后 ,就会把事件交给第一响应对象来处理,如果第一响应对象能顺利处理事件,则整个响应结束 ,但是第一响应对象如果无法处理事件,就会把事件传递给下一个响应对象(nextResponder),一直沿着响应链向上回溯 。那么第一响应对象的下一响应对象是谁呢?我们结合下图进行解释:
左边为例:
1. 如果接收到事件的初始View无法处理事件, 那么这个事件会交给他的SuperView, 因为他不是viewController等级中的最高级View。
2. SuperView尝试处理事件,如果SuperView无法处理 ,则这个事件会交给他的SuperView,因为他不是viewController等级中的最高级View。
3. 这样事件就传递到viewController等级中的最高级View,如果最高级View不能处理就会彻底给viewController 。
4. viewController尝试处理事件 ,如果无法处理就传递给Window,Window尝试处理,无法处理就传递给Application。
5. Application尝试处理 ,如果无法处理就就丢弃该事件。
总之,当view无法处理事件时,如果是最高级view ,并存在viewController,则传递给viewController,否则传递给SuperView ,继续往上尝试处理事件 。
view -> ViewController -> window -> Application -> 丢弃
1. 遍历查找最佳响应者时,从所有子视图的最上层view往下遍历(从subviews数组最后一个元素往前便利)。
2. 遍历查找最佳响应者时,当一个子视图告诉OS没有被点击时,则它的子视图不会被检查(类似二分法)。
3. 子视图在父视图边界外时 ,并且父亲的clipsToBounds属性为false时,子视图接受不到事件 。
4. 一个UIWindow对象在某一时刻只能有一个响应者对象可以成为第一响应者。
5. 成为第一响应者必须要canBecomeFirstResponder,才能becomeFirstResponder。
6. 手动设置某个view becomeFirstResponder时 ,当有事件发生时,该view不一定最先响应。比如点击button时会触发自身响应,而不管有无其他becomeFirstResponder的view 。
7. 第一响应者主要体现在 ,事件发生时没有响应者出来处理事件,这时候第一响应者就会尝试处理事件。
如何在tableviewcell点击后跳转到另一个view
首先选择行数selectRowAtIndexes:
滚动的话tableview的superview时scrollview,scrollview可以滚动到某个position
那么就要计算这个position
position = table row height * index
项目过程中各种具体方法的实现!
1、设置View的backgroundcolor像TableiewGrouped那种风格:
[font=][UIColor groupTableViewBackgroundColor]
[font=]2 、关于tableview的移动距离 ,可以用下面的delegate实现
- (void)scrollViewDidScroll:(UIScrollView *)sender
具体的移动长度可以利用contentOffset求得
3、使得tableview在界面启动后定位在某一行
在viewDidLoad中加入以下代码
NSIndexPath *idxPath = [NSIndexPath indexPathForRow:5 inSection:0];
[self.tableView scrollToRowAtIndexPath:idxPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:NO];
4、如果希望iPhone App里包含让tableView滚到顶部的功能,注意UITabelView 继承自UIScrollView,而setContentOffset是scrollview里头一个方法。
[pre]- (void)scrollToTop:(BOOL)animated {
[self setContentOffset:CGPointMake(0,0) animated:animated];
}
- (void)scrollToBottom:(BOOL)animated {
NSUInteger sectionCount = [self numberOfSections];
if (sectionCount) {
NSUInteger rowCount = [self numberOfRowsInSection:0];
if (rowCount) {
NSUInteger ii[2] = {0, rowCount-1};
NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:ii length:2];
[self scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom
animated:animated];
}
}
}
实现代码如下:
UIViewController *controller;
UIView *view = self.view;
while (1)
{
controller = (UIViewController *)view.nextResponder;
if (![controller isKindOfClass:[UIViewControllerclass]] || controller.navigationController == nil)
view = view.superview;
else
break;
}
关于“从用户点击屏幕到程序作出反应之间都发生了什么?”这个话题的介绍 ,今天小编就给大家分享完了,如果对你有所帮助请保持对本站的关注!
本文来自作者[火星引力]投稿,不代表缔安号立场,如若转载,请注明出处:https://oxylanechinavideo.com/cshi/202504-268.html
评论列表(4条)
我是缔安号的签约作者“火星引力”!
希望本篇文章《从用户点击屏幕到程序作出反应之间都发生了什么?》能对你有所帮助!
本站[缔安号]内容主要涵盖:国足,欧洲杯,世界杯,篮球,欧冠,亚冠,英超,足球,综合体育
本文概览:网上科普有关“从用户点击屏幕到程序作出反应之间都发生了什么?”话题很是火热,小编也是针对从用户点击屏幕到程序作出反应之间都发生了什么?寻找了一些与之相关的一些信息进行分析,如果...