chore: Initial clean commit
- Removed YuMi/Library/ (138 MB, not tracked) - Removed YuMi/Resources/ (23 MB, not tracked) - Removed old version assets (566 files, not tracked) - Excluded Pods/, xcuserdata/ and other build artifacts - Clean repository optimized for company server deployment
This commit is contained in:
40
YuMi/CustomUI/UIButton/UIButton+EnlargeTouchArea.h
Normal file
40
YuMi/CustomUI/UIButton/UIButton+EnlargeTouchArea.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// UIButton+EnlargeTouchArea.h
|
||||
// XCCategrayKit
|
||||
//
|
||||
// Created by Macx on 2018/8/30.
|
||||
// Copyright © 2018年 KevinWang. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIButton (EnlargeTouchArea)
|
||||
@property (nonatomic, assign) NSTimeInterval yn_acceptEventInterval; // 重复点击的间隔
|
||||
|
||||
//图片frmae
|
||||
@property (strong, nonatomic) NSValue *imageFrame;
|
||||
//标题frmae
|
||||
@property (strong, nonatomic) NSValue *titleFrame;
|
||||
|
||||
/**
|
||||
通过 hitTest:withEvent: 扩大btn的点击范围
|
||||
注:填写的都是 在button 原frame 上面 扩大的对应的值
|
||||
|
||||
@param top 顶部 扩大的值
|
||||
@param right 右边 扩大的值
|
||||
@param bottom 底部 扩大的值
|
||||
@param left 左边 扩大的值
|
||||
*/
|
||||
- (void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left;
|
||||
|
||||
/**
|
||||
扩大按钮点击范围
|
||||
|
||||
@discussion setEnlargeEdgeWithTop:right:bottom:left:方法的包装
|
||||
*/
|
||||
- (void)enlargeTouchArea:(UIEdgeInsets)insets;
|
||||
|
||||
|
||||
+(UIButton *)buttonInitWithText:(NSString *)text font:(UIFont *)font textColor:(UIColor *)textColor image:(UIImage *)image bgImage:(UIImage *)bgImage;
|
||||
|
||||
@end
|
192
YuMi/CustomUI/UIButton/UIButton+EnlargeTouchArea.m
Normal file
192
YuMi/CustomUI/UIButton/UIButton+EnlargeTouchArea.m
Normal file
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// UIButton+EnlargeTouchArea.m
|
||||
// XCCategrayKit
|
||||
//
|
||||
// Created by Macx on 2018/8/30.
|
||||
// Copyright © 2018年 KevinWang. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIButton+EnlargeTouchArea.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#define defaultInterval 0.0003 //默认时间间隔,不能太长,以免影响系统拍照等功能
|
||||
@interface UIButton ()
|
||||
/**
|
||||
* bool YES 忽略点击事件 NO 允许点击事件
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL isIgnoreEvent;
|
||||
@end
|
||||
|
||||
@implementation UIButton (EnlargeTouchArea)
|
||||
|
||||
static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
|
||||
static const char *UIControl_enventIsIgnoreEvent = "UIControl_enventIsIgnoreEvent";
|
||||
|
||||
//定义常量 必须是C语言字符串
|
||||
static const char *imageFrameStr = "imageFrame";
|
||||
static const char *titleFrameStr = "titleFrame";
|
||||
|
||||
+ (void)load{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
Method newImageMethod = class_getInstanceMethod(self, @selector(new_imageRectForContentRect:));
|
||||
Method oldImageMethod = class_getInstanceMethod(self, @selector(imageRectForContentRect:));
|
||||
method_exchangeImplementations(newImageMethod, oldImageMethod);
|
||||
|
||||
Method newTitleMethod = class_getInstanceMethod(self, @selector(new_titleRectForContentRect:));
|
||||
Method oldTitleMethod = class_getInstanceMethod(self, @selector(titleRectForContentRect:));
|
||||
method_exchangeImplementations(newTitleMethod, oldTitleMethod);
|
||||
|
||||
|
||||
//根据selector查找Method
|
||||
SEL selA = @selector(sendAction:to:forEvent:);
|
||||
SEL selB = @selector(new_sendAction:to:forEvent:);
|
||||
Method methodA = class_getInstanceMethod(self,selA);
|
||||
Method methodB = class_getInstanceMethod(self, selB);
|
||||
//添加自定义方法
|
||||
BOOL isAdd = class_addMethod(self, selA, method_getImplementation(methodB), method_getTypeEncoding(methodB));
|
||||
|
||||
if (isAdd) {//添加成功->替换
|
||||
class_replaceMethod(self, selB, method_getImplementation(methodA), method_getTypeEncoding(methodA));
|
||||
}else{//添加不成功->交换
|
||||
//添加失败了 说明本类中有methodB的实现,此时只需要将methodA和methodB的IMP互换一下即可。
|
||||
method_exchangeImplementations(methodA, methodB);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
- (void)new_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
|
||||
self.yn_acceptEventInterval = self.yn_acceptEventInterval == 0 ? defaultInterval : self.yn_acceptEventInterval;
|
||||
if (self.isIgnoreEvent){//默认可以响应点击事件
|
||||
return;
|
||||
}
|
||||
if (self.yn_acceptEventInterval > 0){//第一次点击,设定eventTimeInterval后,可以响应点击事件
|
||||
[self performSelector:@selector(setNoIgnoreEvent) withObject:nil afterDelay:self.yn_acceptEventInterval];
|
||||
}
|
||||
self.isIgnoreEvent = YES;//设置不可以响应点击事件
|
||||
[self new_sendAction:action to:target forEvent:event];
|
||||
}
|
||||
|
||||
// runtime 动态绑定 属性
|
||||
- (BOOL)isIgnoreEvent{
|
||||
return [objc_getAssociatedObject(self, UIControl_enventIsIgnoreEvent) boolValue];
|
||||
}
|
||||
-(void)setNoIgnoreEvent{
|
||||
self.isIgnoreEvent = NO;
|
||||
}
|
||||
- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent {
|
||||
objc_setAssociatedObject(self, UIControl_enventIsIgnoreEvent, @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
-(void)setYn_acceptEventInterval:(NSTimeInterval)yn_acceptEventInterval{
|
||||
objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(yn_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
-(NSTimeInterval)yn_acceptEventInterval{
|
||||
return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
|
||||
}
|
||||
- (void)setImageFrame:(NSValue *)imageFrame{
|
||||
objc_setAssociatedObject(self, imageFrameStr, imageFrame, OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
- (NSValue *)imageFrame{
|
||||
return objc_getAssociatedObject(self, imageFrameStr);
|
||||
}
|
||||
|
||||
- (void)setTitleFrame:(NSValue *)titleFrame{
|
||||
objc_setAssociatedObject(self, titleFrameStr, titleFrame, OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
- (NSValue *)titleFrame{
|
||||
return objc_getAssociatedObject(self, titleFrameStr);
|
||||
}
|
||||
|
||||
- (CGRect)new_imageRectForContentRect:(CGRect)contentRect{
|
||||
if (CGRectEqualToRect(self.imageFrame.CGRectValue, CGRectZero)) {
|
||||
return [self new_imageRectForContentRect:contentRect];
|
||||
}
|
||||
return self.imageFrame.CGRectValue;
|
||||
}
|
||||
|
||||
- (CGRect)new_titleRectForContentRect:(CGRect)contentRect{
|
||||
if (CGRectEqualToRect(self.titleFrame.CGRectValue, CGRectZero)) {
|
||||
return [self new_titleRectForContentRect:contentRect];
|
||||
}
|
||||
return self.titleFrame.CGRectValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char topNameKey;
|
||||
static char rightNameKey;
|
||||
static char bottomNameKey;
|
||||
static char leftNameKey;
|
||||
|
||||
- (void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left
|
||||
{
|
||||
objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);
|
||||
}
|
||||
|
||||
- (void)enlargeTouchArea:(UIEdgeInsets)insets
|
||||
{
|
||||
[self setEnlargeEdgeWithTop:insets.top
|
||||
right:insets.right
|
||||
bottom:insets.bottom
|
||||
left:insets.left];
|
||||
}
|
||||
|
||||
- (CGRect)enlargedRect
|
||||
{
|
||||
NSNumber* topEdge = objc_getAssociatedObject(self, &topNameKey);
|
||||
NSNumber* rightEdge = objc_getAssociatedObject(self, &rightNameKey);
|
||||
NSNumber* bottomEdge = objc_getAssociatedObject(self, &bottomNameKey);
|
||||
NSNumber* leftEdge = objc_getAssociatedObject(self, &leftNameKey);
|
||||
if (topEdge && rightEdge && bottomEdge && leftEdge)
|
||||
{
|
||||
return CGRectMake(self.bounds.origin.x - leftEdge.floatValue,
|
||||
self.bounds.origin.y - topEdge.floatValue,
|
||||
self.bounds.size.width + leftEdge.floatValue + rightEdge.floatValue,
|
||||
self.bounds.size.height + topEdge.floatValue + bottomEdge.floatValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self.bounds;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
|
||||
{
|
||||
if(self.hidden) return nil;
|
||||
CGRect rect = [self enlargedRect];
|
||||
if (CGRectEqualToRect(rect, self.bounds))
|
||||
{
|
||||
return [super hitTest:point withEvent:event];
|
||||
}
|
||||
return CGRectContainsPoint(rect, point) ? self : nil;
|
||||
}
|
||||
+(UIButton *)buttonInitWithText:(NSString *)text font:(UIFont *)font textColor:(UIColor *)textColor image:(UIImage *)image bgImage:(UIImage *)bgImage{
|
||||
UIButton *button = [[UIButton alloc]initWithFrame:CGRectZero];
|
||||
if(text.length > 0){
|
||||
[button setTitle:text forState:UIControlStateNormal];
|
||||
}
|
||||
if(font != nil){
|
||||
button.titleLabel.font = font;
|
||||
}
|
||||
|
||||
if(textColor != nil){
|
||||
[button setTitleColor:textColor forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
if (image != nil){
|
||||
[button setImage:image forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
if(bgImage != nil){
|
||||
[button setBackgroundImage:bgImage forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
@end
|
Reference in New Issue
Block a user