修复消息页面部分bug

This commit is contained in:
wbzhan
2019-05-27 16:41:39 +08:00
parent 25c051d5f1
commit 8e027e82c9
16 changed files with 355 additions and 546 deletions
+10 -10
View File
@@ -7,19 +7,19 @@
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ImagePosition) {
ImagePositionLeft = 0, // 图片在左,文字在右,默认
ImagePositionRight, // 图片在右,文字在左
ImagePositionTop, // 图片在上,文字在下
ImagePositionBottom, // 图片在下,文字在上
};
#define defaultInterval 0.01//默认时间间隔
//typedef NS_ENUM(NSInteger, ImagePosition) {
// ImagePositionLeft = 0, // 图片在左,文字在右,默认
// ImagePositionRight, // 图片在右,文字在左
// ImagePositionTop, // 图片在上,文字在下
// ImagePositionBottom, // 图片在下,文字在上
//};
//#define defaultInterval 0.01//默认时间间隔
@interface UIButton (button)
/**
* 为按钮添加点击间隔 eventTimeInterval秒
*/
@property(nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;//响应范围负值为扩大,正值为缩小
@property (nonatomic, assign) NSTimeInterval timeInterval;
- (void)setImagePosition:(ImagePosition)postion spacing:(CGFloat)spacing;//设置图片与文字具体位置与间距
//@property(nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;//响应范围负值为扩大,正值为缩小
//@property (nonatomic, assign) NSTimeInterval timeInterval;
//- (void)setImagePosition:(ImagePosition)postion spacing:(CGFloat)spacing;//设置图片与文字具体位置与间距
@end
+143 -143
View File
@@ -10,15 +10,15 @@
#import <objc/runtime.h>
@interface UIButton()
@property (nonatomic, assign) BOOL isIgnoreEvent;
// @property (nonatomic, assign) BOOL isIgnoreEvent;
@end
@implementation UIButton (button)
@dynamic hitTestEdgeInsets;
//@dynamic hitTestEdgeInsets;
static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";
static const char *UIControl_timeInterval = "UIControl_timeInterval";
static const char *UIControl_enventIsIgnoreEvent = "UIControl_enventIsIgnoreEvent";
//static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";
//static const char *UIControl_timeInterval = "UIControl_timeInterval";
//static const char *UIControl_enventIsIgnoreEvent = "UIControl_enventIsIgnoreEvent";
-(instancetype)init{
self = [super init];
@@ -31,142 +31,142 @@ static const char *UIControl_enventIsIgnoreEvent = "UIControl_enventIsIgnoreEven
[super setHighlighted:NO];
}
// runtime 动态绑定 属性
- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent
{
objc_setAssociatedObject(self, UIControl_enventIsIgnoreEvent, @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isIgnoreEvent{
return [objc_getAssociatedObject(self, UIControl_enventIsIgnoreEvent) boolValue];
}
- (NSTimeInterval)timeInterval
{
return [objc_getAssociatedObject(self, UIControl_timeInterval) doubleValue];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval
{
objc_setAssociatedObject(self, UIControl_timeInterval, @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)load
{
// Method Swizzling
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selA = @selector(sendAction:to:forEvent:);
SEL selB = @selector(after_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)after_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
self.timeInterval = self.timeInterval == 0 ? defaultInterval : self.timeInterval;
if (self.isIgnoreEvent){
return;
}else if (self.timeInterval > 0){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self setIsIgnoreEvent:NO];
});
}
self.isIgnoreEvent = YES;
// 这里看上去会陷入递归调用死循环,但在运行期此方法是和sendAction:to:forEvent:互换的,相当于执行sendAction:to:forEvent:方法,所以并不会陷入死循环。
[self after_sendAction:action to:target forEvent:event];
}
#pragma mark --点击区域以及button按钮文字位置
- (void)setImagePosition:(ImagePosition)postion spacing:(CGFloat)spacing
{
// [self setTitle:self.currentTitle forState:UIControlStateNormal];
// [self setImage:self.currentImage forState:UIControlStateNormal];
CGFloat imageWidth = self.imageView.image.size.width;
CGFloat imageHeight = self.imageView.image.size.height;
CGFloat labelWidth = [self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
if (postion == ImagePositionRight && labelWidth >= self.frame.size.width - imageWidth) {
labelWidth = self.frame.size.width - imageWidth;
}
CGFloat labelHeight = [self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].height;
CGFloat imageOffsetX = (imageWidth + labelWidth) / 2 - imageWidth / 2; //image中心移动的x距离
CGFloat imageOffsetY = imageHeight / 2 + spacing / 2; //image中心移动的y距离
CGFloat labelOffsetX = (imageWidth + labelWidth / 2) - (imageWidth + labelWidth) / 2; //label中心移动的x距离
CGFloat labelOffsetY = labelHeight / 2 + spacing / 2; //label中心移动的y距离
CGFloat tempWidth = MAX(labelWidth, imageWidth);
CGFloat changedWidth = labelWidth + imageWidth - tempWidth;
CGFloat tempHeight = MAX(labelHeight, imageHeight);
CGFloat changedHeight = labelHeight + imageHeight + spacing - tempHeight;
switch (postion) {
case ImagePositionLeft:
self.imageEdgeInsets = UIEdgeInsetsMake(0, -spacing / 2, 0, spacing / 2);
self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, -spacing / 2);
self.contentEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, spacing / 2);
break;
case ImagePositionRight:
self.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth + spacing / 2, 0, -(labelWidth + spacing / 2));
self.titleEdgeInsets = UIEdgeInsetsMake(0, -(imageWidth + spacing / 2), 0, imageWidth + spacing / 2);
self.contentEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, spacing / 2);
break;
case ImagePositionTop:
self.imageEdgeInsets = UIEdgeInsetsMake(-imageOffsetY, imageOffsetX, imageOffsetY, -imageOffsetX);
self.titleEdgeInsets = UIEdgeInsetsMake(labelOffsetY, -labelOffsetX, -labelOffsetY, labelOffsetX);
self.contentEdgeInsets = UIEdgeInsetsMake(imageOffsetY, -changedWidth / 2, changedHeight - imageOffsetY, -changedWidth / 2);
break;
case ImagePositionBottom:
self.imageEdgeInsets = UIEdgeInsetsMake(imageOffsetY, imageOffsetX, -imageOffsetY, -imageOffsetX);
self.titleEdgeInsets = UIEdgeInsetsMake(-labelOffsetY, -labelOffsetX, labelOffsetY, labelOffsetX);
self.contentEdgeInsets = UIEdgeInsetsMake(changedHeight - imageOffsetY, -changedWidth / 2, imageOffsetY, -changedWidth / 2);
break;
default:
break;
}
}
-(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets
{
NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(UIEdgeInsets)hitTestEdgeInsets
{
NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
if(value) {
UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
}else {
return UIEdgeInsetsZero;
}
}
//点击区域
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) {
return [super pointInside:point withEvent:event];
}
CGRect relativeFrame = self.bounds;
CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
return CGRectContainsPoint(hitFrame, point);
}
//// runtime 动态绑定 属性
//- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent
//{
// objc_setAssociatedObject(self, UIControl_enventIsIgnoreEvent, @(isIgnoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//}
//- (BOOL)isIgnoreEvent{
// return [objc_getAssociatedObject(self, UIControl_enventIsIgnoreEvent) boolValue];
//}
//
//- (NSTimeInterval)timeInterval
//{
// return [objc_getAssociatedObject(self, UIControl_timeInterval) doubleValue];
//}
//
//- (void)setTimeInterval:(NSTimeInterval)timeInterval
//{
// objc_setAssociatedObject(self, UIControl_timeInterval, @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//}
//
//+ (void)load
//{
// // Method Swizzling
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
// SEL selA = @selector(sendAction:to:forEvent:);
// SEL selB = @selector(after_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)after_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
//{
// self.timeInterval = self.timeInterval == 0 ? defaultInterval : self.timeInterval;
// if (self.isIgnoreEvent){
// return;
// }else if (self.timeInterval > 0){
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeInterval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// [self setIsIgnoreEvent:NO];
// });
// }
//
// self.isIgnoreEvent = YES;
// // 这里看上去会陷入递归调用死循环,但在运行期此方法是和sendAction:to:forEvent:互换的,相当于执行sendAction:to:forEvent:方法,所以并不会陷入死循环。
// [self after_sendAction:action to:target forEvent:event];
//}
//#pragma mark --点击区域以及button按钮文字位置
//- (void)setImagePosition:(ImagePosition)postion spacing:(CGFloat)spacing
//{
//// [self setTitle:self.currentTitle forState:UIControlStateNormal];
//// [self setImage:self.currentImage forState:UIControlStateNormal];
//
// CGFloat imageWidth = self.imageView.image.size.width;
// CGFloat imageHeight = self.imageView.image.size.height;
// CGFloat labelWidth = [self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].width;
//
// if (postion == ImagePositionRight && labelWidth >= self.frame.size.width - imageWidth) {
// labelWidth = self.frame.size.width - imageWidth;
// }
//
// CGFloat labelHeight = [self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName:self.titleLabel.font}].height;
//
// CGFloat imageOffsetX = (imageWidth + labelWidth) / 2 - imageWidth / 2; //image中心移动的x距离
// CGFloat imageOffsetY = imageHeight / 2 + spacing / 2; //image中心移动的y距离
// CGFloat labelOffsetX = (imageWidth + labelWidth / 2) - (imageWidth + labelWidth) / 2; //label中心移动的x距离
// CGFloat labelOffsetY = labelHeight / 2 + spacing / 2; //label中心移动的y距离
//
// CGFloat tempWidth = MAX(labelWidth, imageWidth);
// CGFloat changedWidth = labelWidth + imageWidth - tempWidth;
// CGFloat tempHeight = MAX(labelHeight, imageHeight);
// CGFloat changedHeight = labelHeight + imageHeight + spacing - tempHeight;
//
// switch (postion) {
// case ImagePositionLeft:
// self.imageEdgeInsets = UIEdgeInsetsMake(0, -spacing / 2, 0, spacing / 2);
// self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, -spacing / 2);
// self.contentEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, spacing / 2);
// break;
//
// case ImagePositionRight:
// self.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth + spacing / 2, 0, -(labelWidth + spacing / 2));
// self.titleEdgeInsets = UIEdgeInsetsMake(0, -(imageWidth + spacing / 2), 0, imageWidth + spacing / 2);
// self.contentEdgeInsets = UIEdgeInsetsMake(0, spacing / 2, 0, spacing / 2);
// break;
//
// case ImagePositionTop:
// self.imageEdgeInsets = UIEdgeInsetsMake(-imageOffsetY, imageOffsetX, imageOffsetY, -imageOffsetX);
// self.titleEdgeInsets = UIEdgeInsetsMake(labelOffsetY, -labelOffsetX, -labelOffsetY, labelOffsetX);
// self.contentEdgeInsets = UIEdgeInsetsMake(imageOffsetY, -changedWidth / 2, changedHeight - imageOffsetY, -changedWidth / 2);
// break;
//
// case ImagePositionBottom:
// self.imageEdgeInsets = UIEdgeInsetsMake(imageOffsetY, imageOffsetX, -imageOffsetY, -imageOffsetX);
// self.titleEdgeInsets = UIEdgeInsetsMake(-labelOffsetY, -labelOffsetX, labelOffsetY, labelOffsetX);
// self.contentEdgeInsets = UIEdgeInsetsMake(changedHeight - imageOffsetY, -changedWidth / 2, imageOffsetY, -changedWidth / 2);
// break;
//
// default:
// break;
// }
//}
//
//-(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets
//{
// NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
// objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//}
//
//-(UIEdgeInsets)hitTestEdgeInsets
//{
// NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
// if(value) {
// UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
// }else {
// return UIEdgeInsetsZero;
// }
//}
////点击区域
//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
//{
// if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) || !self.enabled || self.hidden) {
// return [super pointInside:point withEvent:event];
// }
//
// CGRect relativeFrame = self.bounds;
// CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);
//
// return CGRectContainsPoint(hitFrame, point);
//}
@end