事件是不是系统事件,是系统事件交给代理处理(比如程序启动完成时交给代理开启一个runRoop);
不是系统事件就交给主窗口处理(keyWindow);
主窗口会在视图中找到最合适的视图来处理触摸事件;
事件传递的过程-事件处理的过程(谁能处理)----
// 04-事件的产生和传递
#import "XMGWindow.h"
@implementation XMGWindow
// 事件传递的时候调用
// 什么时候调用:当事件传递给控件的时候,就会调用控件的这个方法,去寻找最合适的view
// 作用:寻找最合适的view
// point:当前的触摸点,point这个点的坐标系就是方法调用者
//- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
//{
// // 调用系统的做法去寻找最合适的view,返回最合适的view
// UIView *fitView = [super hitTest:point withEvent:event];
//
//// NSLog(@"fitView--%@",fitView);
// return fitView;
//}
// 作用:判断当前这个点在不在方法调用者(控件)上
//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
//{
// return YES;
//}
//- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
//{
//// NSLog(@"%s",__func__);
//}
// 点击黄色视图 -》 事件 -》 UIApplication -> UIWindow
// 因为所有的视图类都是继承BaseView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// 1.判断当前控件能否接收事件
if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
// 2. 判断点在不在当前控件
if ([self pointInside:point withEvent:event] == NO) return nil;
// 3.从后往前遍历自己的子控件
NSInteger count = self.subviews.count;
for (NSInteger i = count - 1; i >= 0; i--) {
UIView *childView = self.subviews[i];
// 把当前控件上的坐标系转换成子控件上的坐标系
CGPoint childP = [self convertPoint:point toView:childView];
UIView *fitView = [childView hitTest:childP withEvent:event];
if (fitView) { // 寻找到最合适的view
return fitView;
}
}
// 循环结束,表示没有比自己更合适的view
return self;
}
@end
// BaseView.m
// 04-事件的产生和传递
#import "BaseView.h"
@implementation BaseView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@---touchesBegan",[self class]);
}
// UIApplication -> [UIWindow hitTest:withEvent:] -> whiteView hitTest:withEvent
// 因为所有的视图类都是继承BaseView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// NSLog(@"%@--hitTest",[self class]);
// return [super hitTest:point withEvent:event];
// 1.判断当前控件能否接收事件
if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
// 2. 判断点在不在当前控件
if ([self pointInside:point withEvent:event] == NO) return nil;
// 3.从后往前遍历自己的子控件
NSInteger count = self.subviews.count;
for (NSInteger i = count - 1; i >= 0; i--) {
UIView *childView = self.subviews[i];
// 把当前控件上的坐标系转换成子控件上的坐标系
CGPoint childP = [self convertPoint:point toView:childView];
UIView *fitView = [childView hitTest:childP withEvent:event];
if (fitView) { // 寻找到最合适的view
return fitView;
}
}
// 循环结束,表示没有比自己更合适的view
return self;
}
@end
07-hitText练习1
当从storyboard往类里面拖线的时候发现不能拖,可以反过来从 类文件(xxx.m)拖到storyboard中;
image.png
image.png
// YellowView.m
// 07-hitText练习1
#import "YellowView.h"
@interface YellowView ()
@property (nonatomic, weak) IBOutlet UIButton *btn;
@end
@implementation YellowView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// 当前坐标系上的点转换到按钮上的点
CGPoint btnP = [self convertPoint:point toView:self.btn];
// 判断点在不在按钮上
if ([self.btn pointInside:btnP withEvent:event]) {
// 点在按钮上
return self.btn;
}else{
return [super hitTest:point withEvent:event];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@",self.btn);
NSLog(@"%s",__func__);
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
08-hitText练习2
image.png
// ViewController.m
// 08-hitText练习2
#import "ViewController.h"
#import "PopBtn.h"
@interface ViewController ()
@end
@implementation ViewController
- (IBAction)popChatView:(PopBtn *)sender {
// 弹出对话框
UIButton *chatView = [UIButton buttonWithType:UIButtonTypeCustom];
chatView.bounds = CGRectMake(0, 0, 200, 200);
chatView.center = CGPointMake(100, -100);
[chatView setBackgroundImage:[UIImage imageNamed:@"对话框"] forState:UIControlStateNormal];
[chatView setBackgroundImage:[UIImage imageNamed:@"小孩"] forState:UIControlStateHighlighted];
sender.chatView = chatView;
[sender addSubview:chatView];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
// PopBtn.h
// 08-hitText练习2
#import <UIKit/UIKit.h>
@interface PopBtn : UIButton
@property (nonatomic, weak) UIButton *chatView;
@end
// PopBtn.m
// 08-hitText练习2
#import "PopBtn.h"
@implementation PopBtn
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// 当前控件上的点转换到chatView上
CGPoint chatP = [self convertPoint:point toView:self.chatView];
// 判断下点在不在chatView上
if ([self.chatView pointInside:chatP withEvent:event]) {
return self.chatView;
}else{
return [super hitTest:point withEvent:event];
}
}
//找到合适的事件处理对象,来处理事件;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// 获取UITouch
UITouch *touch = [touches anyObject];
// 获取当前的点
CGPoint curP = [touch locationInView:self];
// 获取上一个的点
CGPoint preP = [touch previousLocationInView:self];
// 获取偏移量
CGFloat offsetX = curP.x - preP.x;
CGFloat OffsetY = curP.y - preP.y;
// 修改控件的位置
CGPoint center = self.center;
center.x += offsetX;
center.y += OffsetY;
self.center = center;
}
@end
网友评论