解析UIControl

解析UIControl

从下图可以看出,UIControl继承自UIView,添加了响应事件功能.

UIButton之所以能响应各种各样的事件是因为继承自UIControl

使用UIControl可以精确的控制按钮事件,我用定制UIControlEventValueChanged来进行说明.

YXControl.h + YXControl.m
//
//  YXControl.h
//  UIControl
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface YXControl : UIControl

@property (nonatomic, strong) UIImage *yesImage;
@property (nonatomic, strong) UIImage *noImage;

- (void)exchange;

@end
//
//  YXControl.m
//  UIControl
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "YXControl.h"

@interface YXControl ()

@property (nonatomic, strong) UIImageView *YesImageView;
@property (nonatomic, strong) UIImageView *NoImageView;

@end


@implementation YXControl

#pragma mark - 重写 getter setter 方法
@synthesize yesImage = _yesImage;
@synthesize noImage  = _noImage;

- (UIImage *)yesImage
{
    return _yesImage;
}

- (void)setYesImage:(UIImage *)yesImage
{
    _yesImage = yesImage;
    _YesImageView.image = yesImage;
}

- (UIImage *)noImage
{
    return _noImage;
}

- (void)setNoImage:(UIImage *)noImage
{
    _noImage = noImage;
    _NoImageView.image = noImage;
}

#pragma mark - 初始化
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        _YesImageView = [[UIImageView alloc] initWithFrame:frame];
        _NoImageView  = [[UIImageView alloc] initWithFrame:frame];
        
        [self addSubview:_YesImageView];
        [self addSubview:_NoImageView];
    }
    return self;
}

#pragma mark - UIControl事件
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    // 获取触摸点坐标
    CGPoint p = [touch locationInView:self];
    NSLog(@"begin    %@", NSStringFromCGPoint(p));
    
    return YES;
}

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    // 获取触摸点坐标
    CGPoint p = [touch locationInView:self];
    NSLog(@"continue %@", NSStringFromCGPoint(p));
    
    return YES;
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    // 获取触摸点坐标
    CGPoint p = [touch locationInView:self];
    NSLog(@"end      %@", NSStringFromCGPoint(p));
    
    // 判断触摸点是否超出了这个view的范围
    if (p.x >= 0 && p.x <= self.bounds.size.width &&
        p.y >= 0 && p.y <= self.bounds.size.height)
    {
        // 发送事件
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}

- (void)cancelTrackingWithEvent:(UIEvent *)event
{

}

- (void)exchange
{
    [self bringSubviewToFront:self.subviews[0]];
}

@end

用于测试用的图片

结果如图下图所示:

//
//  RootViewController.m
//  UIControl
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "YXControl.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];


    // 初始化UIControl
    YXControl *controlView      = [[YXControl alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    controlView.backgroundColor = [UIColor blackColor];
    controlView.center          = self.view.center;
    controlView.yesImage        = [UIImage imageNamed:@"yes"];
    controlView.noImage         = [UIImage imageNamed:@"no"];
    [self.view addSubview:controlView];
    
    // 添加响应事件
    [controlView addTarget:self
                    action:@selector(controlEvent:)
          forControlEvents:UIControlEventValueChanged];
}

- (void)controlEvent:(YXControl *)control
{
    [control exchange];
}

@end

以下三个方法非常重要:

beginTrackingWithTouch:        触摸事件刚刚开始时执行(1次)

continueTrackingWithTouch:   滑动手指后将会一直执行(多次)

endTrackingWithTouch:          松开手指后执行(1次)

以下两个地方也是需要注意的哦:

1. 发送UIControlEventValueChanged事件

2. 注册对应的UIControlEventValueChanged事件

只有这样子,两者之间才能通过addTarget:action:forControlEvents:联系起来.

以下这个小细节也是非常令人意外的,UIControlEventValueChanged这个值是非常独特的呢.

如果使用UIControlEventTouchUpInside,这个事件是UIControl自动发的,不需要你管哦(也就是说不需要你执行sendActionsForControlEvents:)

原文地址:https://www.cnblogs.com/YouXianMing/p/3797226.html