有个问题...
写的时候我设置了诸如<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];
}