源码03-UIView的拖拽

在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象

UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件

默认View是不支持多手指操作的,要设置Multiple Touch

//  RedView.m
//  03-UIView的拖拽
#import "RedView.h"
@implementation RedView
// 当手指开始触摸view
// NSArray,字典,NSSet(无序)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{ 
    NSLog(@"%ld", touches.count);
    NSLog(@"%s",__func__);
}

// 当手指在view上移动的时候
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%s",__func__);
    
    // 获取UITouch对象
    UITouch *touch = [touches anyObject];
    
    // 获取当前点
    CGPoint curP = [touch locationInView:self];
    
    // 获取上一个点
    CGPoint preP = [touch previousLocationInView:self];
    
    // 获取x轴偏移量
    CGFloat offsetX = curP.x - preP.x;
    
    // 获取y轴偏移量
    CGFloat offsetY = curP.y - preP.y;
    
    // 修改view的位置(frame,center,transform)
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
   
//  self.transform = CGAffineTransformMakeTranslation(offsetX, 0);
    
}

// 当手指离开这个view的时候
//- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//     NSLog(@"%s",__func__);
//}

// 当触摸事件被打断的时候调用(电话打入)
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end

04-事件的产生和传递

触摸事件的传递是从父控件传递到子控件

点击了绿色的view:UIApplication -> UIWindow -> 白色 -> 绿色

点击了蓝色的view:UIApplication -> UIWindow -> 白色 -> 橙色 -> 蓝色
点击了黄色的view:UIApplication -> UIWindow -> 白色 -> 橙色 -> 蓝色 -> 黄色
如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件(掌握)
•如何找到最合适的控件来处理事件?
自己是否能接收触摸事件?
触摸点是否在自己身上?
从后往前遍历子控件,重复前面的两个步骤
如果没有符合条件的子控件,那么就自己最适合处理

//  BaseView.m
//  04-事件的产生和传递
#import "BaseView.h"

@implementation BaseView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%@---touchesBegan",[self class]);
}

@end
//  ViewController.m
//  04-事件的产生和传递
#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageV;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [_imageV addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
//  RedView.h
//  04-事件的产生和传递
#import "BaseView.h"

@interface RedView : BaseView

@end
//  RedView.m
//  04-事件的产生和传递
#import "RedView.h"

@implementation RedView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end

05-hitText和pointInside

//  AppDelegate.m
// 04-事件的产生和传递 #import "AppDelegate.h" #import "XMGWindow.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[XMGWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // 加载storyboard UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // 加载箭头指向的控制器 UIViewController *vc = [storyboard instantiateInitialViewController];
// 设置窗口的跟控制器 self.window.rootViewController = vc; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } @end
//  XMGWindow.m
//  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__);
}

@end
//  ViewController.m
//  04-事件的产生和传递
#import "ViewController.h"
// 点击白色: UIApplication -> UIWindow(寻找最合适的view)
@interface ViewController ()

@end

@implementation ViewController
// hitTest:withEvent:作用:就是用来寻找最合适的view
- (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
本人无商业用途,仅仅是学习做个笔记,特别鸣谢小马哥,学习了IOS,另日语学习内容有需要文本和音频请关注公众号:riyuxuexishuji
原文地址:https://www.cnblogs.com/laugh/p/6668173.html