美文网首页iOS技术专题iOS 开发 iOS学习开发
一些实用的Category(自用(不断更新

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

作者: Zhang_yD | 来源:发表于2016-05-24 14:34 被阅读291次

有个问题...
写的时候我设置了诸如<a href="#string_vre">以及<a id="string_vre">的锚点...但是点击没有反应....大家有没有解决的办法???


索引

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


NSString

<a id="string_vre">· 匹配正则表达式(对用户输入信息进行正则匹配</a>

.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

<a id="number_format">· 返回一个NSString类型的具有千分位逗号的数字</a>

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

NSDictionary

<a id="dictionary_font_color">· 获得一个存放字体和颜色属性的字典(和富文本搭配使用</a>

.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

<a id="attrbute_string_font_color">· 获得一个富文本,可以由两种字体和颜色组成(两种比较常用</a>

.h
+ (instancetype)attributedStringWithString:(NSString *)string attributes:(nullable NSDictionary<NSString *, id> *)attr subStr:(NSString *)subStr subStrAttributes:(nullable NSDictionary<NSString *, id> *)subStrAttr;
+ (instancetype)attributedStringWithString:(NSString *)string attributes:(nullable NSDictionary<NSString *, id> *)attr subStr:(NSString *)subStr subStrAttributes:(nullable NSDictionary<NSString *, id> *)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

<a id="color_hex">· 设置颜色(16位颜色值转换RGB</a>

.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

<a id="view_corner">· 对View设置圆角(在layoutSubviews里面进行调用 (适合少数量View的圆角设置</a>

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

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

.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拿到了,自然由我们折腾。

<a id="view_shadow">· 给View的四周添加阴影,阴影的效果(这里是画出四个二元曲线</a>

.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

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

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

<a id="scrollview_offset">· 设置ScrollView的偏移(用户输入信息的时候浮动TextField</a>

- (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

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

.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(自用(不断更新

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

  • iOS好项目收集

    在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新

  • 优秀第三方框架推荐

    在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新

  • 代码命名记录

    代码习惯记录 自用标识符 dg:delegate(代理方法前缀) cg:category (分类方法前缀) bk:...

  • iOS开源项目组件

    在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新项目简述日期 JHChainableAnimatio...

  • junit几个实用功能

    Junit有不少实用的功能,如组合(SuiteClasses)、分类(Category)、排序(FixMethod...

  • 实用软件(自用)

    下载相关 Free Download Manager : 比迅雷9浏览器好用无数倍的下载软件 百度云破解版:提供一...

  • 自用实用小总结

    可以直接用的动画库:https://animista.net/play/basic[https://animist...

  • Objective-C 基础类的一些实用 Category

    一、什么是 Category ?Category模式用于向已经存在的类添加方法从而达到扩展已有类的目的,在很多情形...

  • 扩大人脉圈的实用社交技巧(2)

    本节内容大纲 今天是我们第三天阅读《别独自用餐》这本书。 今天我们继续介绍一些实用的社交技巧,其中第一个就是我自己...

网友评论

    本文标题:一些实用的Category(自用(不断更新

    本文链接:https://www.haomeiwen.com/subject/vsszrttx.html