一些实用的Category(自用(不断更新

有个问题...
写的时候我设置了诸如以及的锚点...但是点击没有反应....大家有没有解决的办法???


索引

NSString
· 匹配正则表达式
NSNumber
· 返回有千分位符号的格式字符串
NSDictionary
· 获取字体颜色属性字典(富文本结合使用)
NSAttributedString
· 获取由两种字体颜色组成的富文本
UIColor
· 设置颜色(以0x123456格式输入)
UIView
· 设置圆角
· 添加/移去一个警示标语
· 给View的四周设置阴影
UIButton
· 添加一个倒数计时器
UIScrollView
· 设置自动偏移量
UIBarButtonItem
· 返回按键[new]


NSString

· 匹配正则表达式(对用户输入信息进行正则匹配

.h
typedef NS_ENUM(NSUInteger, VREType) {
    VRETypeUsername = 0, // 用户名
    VRETypeIDCard,  // 身份证号码
    VRETypeBankCard,  // 银行卡号码
    VRETypePhoneNumber,  // 电话号码
    VRETypePassword, // 密码
    VRETypeAddressName,  // 姓名
    VRETypePostalcode,  // 邮箱
    VRETypeAddress,  // 地址
    VRETypeVerifyCode  // 验证码
};
- (BOOL)isValidateRegularExpressionWithType:(VREType)type;
.m
- (BOOL)isValidateRegularExpressionWithType:(VREType)type {
    
    static NSDictionary *verDict;
    if (!verDict) {
        verDict = @{@(VRETypeUsername) : @"^.{1,20}$",
                 @(VRETypeIDCard) : @"^.{18}$",
                 @(VRETypeBankCard) : @"(\\d|\\s){16,22}",
                 @(VRETypePhoneNumber) : @"\\d{11}",
                 @(VRETypePassword) : @"^([a-zA-Z]+|\\d+){8,16}$",
                 @(VRETypeAddressName) : @"^.{1,20}$",
                 @(VRETypePostalcode) : @"\\d{6}",
                 @(VRETypeAddress) : @"^.{0,128}$",
                 @(VRETypeVerifyCode) : @"^[A-Za-z0-9]{4}$"};
    }
    
    if (!verDict[@(type)]) {
        NSLog(@"正则表达式不存在");
        return NO;
    }
    
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", verDict[@(type)]];
    return [predicate evaluateWithObject:self];
}

NSNumber

· 返回一个NSString类型的具有千分位逗号的数字

.h
- (NSString *)formaterWithDecimalStyle;
.m
- (NSString *)formaterWithDecimalStyle {
    
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    return [formatter stringFromNumber:self];
}

NSDictionary

· 获得一个存放字体和颜色属性的字典(和富文本搭配使用

.h
+ (instancetype)attrDictWithFont:(UIFont *)font color:(UIColor *)color;
+ (instancetype)attrDictWithFont:(UIFont *)font color:(UIColor *)color {
    NSMutableDictionary *mDict = [[NSMutableDictionary alloc] init];
    if (font) {
        [mDict setObject:font forKey:NSFontAttributeName];
    }
    if (color) {
        [mDict setObject:color forKey:NSForegroundColorAttributeName];
    }
    return mDict;
}

NSAttributedString

· 获得一个富文本,可以由两种字体和颜色组成(两种比较常用

.h
+ (instancetype)attributedStringWithString:(NSString *)string attributes:(nullable NSDictionary *)attr subStr:(NSString *)subStr subStrAttributes:(nullable NSDictionary *)subStrAttr;
+ (instancetype)attributedStringWithString:(NSString *)string attributes:(nullable NSDictionary *)attr subStr:(NSString *)subStr subStrAttributes:(nullable NSDictionary *)subStrAttr {
    
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] init];
    [attrStr appendAttributedString:[[NSAttributedString alloc] initWithString:string attributes:attr]];
    if (subStr) {
        [attrStr appendAttributedString:[[NSAttributedString alloc] initWithString:subStr attributes:subStrAttr]];
    }
    return attrStr;
}

UIColor

· 设置颜色(16位颜色值转换RGB

.h
+ (UIColor *)colorWithHex:(NSInteger)hexValue;
+ (UIColor *)colorWithHex:(NSInteger)hexValue alpha:(CGFloat)alphaValue;
.m
+ (UIColor *)colorWithHex:(NSInteger)hexValue {
     return [self colorWithHex:hexValue alpha:1.0];
}

+ (UIColor *)colorWithHex:(NSInteger)hexValue alpha:(CGFloat)alphaValue {
    return [self colorWithRed:((float)((hexValue & 0xFF0000) >> 16)) / 255.0
                           green:((float)((hexValue & 0xFF00) >> 8)) / 255.0
                            blue:((float)(hexValue & 0xFF)) / 255.0 alpha:alphaValue];
}

UIView

· 对View设置圆角(在layoutSubviews里面进行调用 (适合少数量View的圆角设置

.h
- (void)makeCornerWithRadius:(float)radius;
.m
- (void)makeCornerWithRadius:(float)radius {
    self.layer.cornerRadius = self.frame.size.width * radius;
    self.layer.masksToBounds = YES;   
}

· 添加/移去一个警示标语(当用户在TextField里面输入了错误信息的时候提示使用

.h
- (void)showRegularExpressionAlertMessage:(NSString *)message;
- (void)removeRegularExpressionAlertMessage;
.m
#define kSubViewTag 1024
- (void)showRegularExpressionAlertMessage:(NSString *)message {
    if ([self viewWithTag:kSubViewTag]) return;
    UILabel *label = [[UILabel alloc] init];
    [self addSubview:label];
    label.text = message;
    label.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
    label.textColor = [UIColor redColor];
    label.alpha = 0;
    label.tag = kSubViewTag;
    label.font = [UIFont systemFontOfSize:13];
    label.textAlignment = NSTextAlignmentRight;
    label.frame = CGRectMake(self.frame.size.width, 0, self.frame.size.width, self.frame.size.height);
    [UIView animateWithDuration:0.3 animations:^{
        CGRect frame = label.frame;
        frame.origin.x = 0;
        label.frame = frame;
        label.alpha = 1;
    }];
}

- (void)removeRegularExpressionAlertMessage {
    UIView *view = [self viewWithTag:kSubViewTag];
    if (view) {
        [UIView animateWithDuration:0.5 animations:^{
            CGRect frame = view.frame;
            frame.origin.x = self.frame.size.width;
            view.frame = frame;
            view.alpha = 0;
        } completion:^(BOOL finished) {
            [view removeFromSuperview];
        }];
    }
}

这里是直接盖一层控件上去,也可以直接修改原View的layer,比如一个小红框(需要提示的View拿到了,自然由我们折腾。

· 给View的四周添加阴影,阴影的效果(这里是画出四个二元曲线

.h
- (void)makeShadow;
.m
- (void)makeShadow {
    self.layer.shadowColor = [UIColor colorWithHex:0x6e6e6e].CGColor;//shadowColor阴影颜色
    self.layer.shadowOffset = CGSizeMake(0,0);//shadowOffset阴影偏移,默认(0, -3),这个跟shadowRadius配合使用
    self.layer.shadowOpacity = 1;//阴影透明度,默认0
    self.layer.shadowRadius = 2;//阴影半径,默认3
    
    //路径阴影
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    float width = self.bounds.size.width;
    float height = self.bounds.size.height;
    float x = self.bounds.origin.x;
    float y = self.bounds.origin.y;
    float addWH = 10;
    
    CGPoint topLeft     = self.bounds.origin;
    CGPoint topRight    = CGPointMake(x+width,y);
    CGPoint bottomRight = CGPointMake(x+width,y+height);
    CGPoint bottomLeft  = CGPointMake(x,y+height);
    
    CGPoint topMiddle    = CGPointMake(x+(width/2),y-addWH);
    CGPoint leftMiddle   = CGPointMake(x-addWH,y+(height/2));
    CGPoint rightMiddle  = CGPointMake(x+width+addWH,y+(height/2));
    CGPoint bottomMiddle = CGPointMake(x+(width/2),y+height+addWH);
    
    [path moveToPoint:topLeft];
    //添加四个二元曲线
    [path addQuadCurveToPoint:topRight
                 controlPoint:topMiddle];
    [path addQuadCurveToPoint:bottomRight
                 controlPoint:rightMiddle];
    [path addQuadCurveToPoint:bottomLeft
                 controlPoint:bottomMiddle];
    [path addQuadCurveToPoint:topLeft
                 controlPoint:leftMiddle];
    //设置阴影路径
    self.layer.shadowPath = path.CGPath;
}

UIButton

· 一句代码实现初始化一个发送验证码倒计时的Button(在ViewDidLoad里面就可以初始化(在开始的Block里面调用接口UIButton

2016.5.27 update

对计时机制做了优化。
原始的方式是通过内存中存储的count数进行递减。
当app处于后台的时候,程序并没有持续进行,实际的时间差和显示的有出入。
更新使用了本地时间戳来判断,较原先方法更为准确。
同时对移除控件时候做了判断,清除缓存数据。

.h
typedef void(^StartBlock)(void);
typedef void(^CompleteBlock)(void);
- (void)addTimerForVerifyWithInterval:(NSUInteger)interval start:(StartBlock)startBlock complete:(CompleteBlock)completeBlock;
.m
#define kVerifyMsgTake @"获取验证码"
#define kVerifyMsgDidToke @"验证码已发送"
#define kVerifyMsgLoad @"秒后重新获取"

static const char *verifyStartBlockKey    = "verifyStartBlockKey";     // 开始回调
static const char *verifyCompleteBlockKey = "verifyCompleteBlockKey";  // 完成回调
static const char *verifyTimerKey         = "verifyTimerKey";          // 计时器
static const char *verifyStatusKey        = "verifyStatusKey";         // 状态(移除时候判断用
static const char *verifyIntervalKey      = "verifyIntervalKey";       // 总时间
static const char *verifyStartIntervalKey = "verifyStartIntervalKey";  // 开始时间戳

#pragma mark -
- (void)addTimerForVerifyWithInterval:(NSUInteger)interval start:(StartBlock)startBlock complete:(CompleteBlock)completeBlock {
    
    [self setTitle:kVerifyMsgTake forState:UIControlStateNormal];
    
    [self addTarget:self action:@selector(verifyButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    
    if (startBlock) {
        objc_setAssociatedObject(self, verifyStartBlockKey, startBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    if (completeBlock) {
        objc_setAssociatedObject(self, verifyCompleteBlockKey, completeBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    objc_setAssociatedObject(self, verifyIntervalKey, @(interval), OBJC_ASSOCIATION_ASSIGN);
    objc_setAssociatedObject(self, verifyStatusKey, @(YES), OBJC_ASSOCIATION_ASSIGN);
}

- (void)verifyButtonClick:(UIButton *)button {
    if (!button.enabled) return;
    
    long long startTime = [[NSDate date] timeIntervalSince1970];
    objc_setAssociatedObject(self, verifyStartIntervalKey, @(startTime), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    void(^startBlock)(void) = objc_getAssociatedObject(self, verifyStartBlockKey);
    if (startBlock) {
        startBlock();
    }
    
    button.enabled = NO;
    [button setTitle:kVerifyMsgDidToke forState:UIControlStateDisabled];
    
    [self startTimer];
}

- (void)startTimer {
    NSTimer *timer = objc_getAssociatedObject(self, verifyTimerKey);
    if (!timer) {
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(reloadTimeStatus) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        objc_setAssociatedObject(self, verifyTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
}

- (void)stopTimer {
    NSTimer *timer = objc_getAssociatedObject(self, verifyTimerKey);
    if (timer) {
        [timer invalidate];
        timer = nil;
        objc_setAssociatedObject(self, verifyTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
}

- (void)reloadTimeStatus {
    long long nowTime = [[NSDate date] timeIntervalSince1970];
    long long startTime = [objc_getAssociatedObject(self, verifyStartIntervalKey) longLongValue];
    int totalTime = [objc_getAssociatedObject(self, verifyIntervalKey) intValue];
    
    if (nowTime - startTime >= totalTime) {
        [self stopTimer];
        self.enabled = YES;
        
        void(^completeBlock)(void) = objc_getAssociatedObject(self, verifyCompleteBlockKey);
        
        if (completeBlock) {
            completeBlock();
        }
        return;
    }
    [self setTitle:[NSString stringWithFormat:@"%lld%@", totalTime - (nowTime - startTime), kVerifyMsgLoad] forState:UIControlStateDisabled];
}

- (void)removeFromSuperview {
    if ([objc_getAssociatedObject(self, verifyStatusKey) boolValue]) {
        objc_removeAssociatedObjects(self);
    }
    [super removeFromSuperview];
}

UIScrollView

· 设置ScrollView的偏移(用户输入信息的时候浮动TextField

- (void)moveWithOffset:(CGFloat)offset;
- (void)moveWithOffset:(CGFloat)offset {
    if (self.contentInset.top != offset) {
        [UIView animateWithDuration:0.3 animations:^{
            self.contentInset = UIEdgeInsetsMake(offset, 0, 0, 0);
        }];
    }
}

UIBarButtonItem

· 导航栏被自定义,或者某个页面需要对导航栏的返回按键单独处理的时候可以使用(单纯为了节约代码)
建议根据需求把图片名字或者Title提出来作为参数。

.h
+ (instancetype)backBarButtonWithTarget:(id)target action:(SEL)action;
.m
+ (instancetype)backBarButtonWithTarget:(id)target action:(SEL)action {

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    [button setImage:[UIImage imageNamed:@"一张返回图片"] forState:UIControlStateNormal];
    button.frame = CGRectMake(0, 0, 30, 30);
    // 控制图片的缩进大小
    [button setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    return [[self alloc] initWithCustomView:button];
}

GitHub传送门:ZExtensions

你可能感兴趣的:(一些实用的Category(自用(不断更新)