一些工作中用到的方法,会持续更新
使用方法:对照目录按标题进行搜索(Command+f)
目录
- 文本框输入时使当前TextField移动到弹出的键盘顶部
- 判断是否为正确的手机号码
- 判断当前版本号
- 使用SDWebImage当收到内存警告时清除缓存
- KVO模式监听数组的变化
- ScrollView及其子类下拉放大头部图片
文本框输入时使当前TextField移动到弹出的键盘顶部
//首先先设置TextField的代理为self,并添加
//然后通过代理方法来处理视图的上下移动
#pragma mark - TextField delegete 处理键盘弹出时视图的上下移动
//键盘上移
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect frame = textField.frame;
CGFloat heights = self.view.frame.size.height;
// 当前点击textfield的坐标的Y值 + 当前点击textFiled的高度 - (屏幕高度- 键盘高度 - 键盘上tabbar高度)
// 在这一部 就是了一个 当前textfile的的最大Y值 和 键盘的最全高度的差值,用来计算整个view的偏移量
int offset = frame.origin.y + frame.size.height - ( heights - 216.0-49.0);//键盘高度216
NSTimeInterval animationDuration = 0.30f;
[UIView beginAnimations:@"ResizeForKeyBoard" context:nil];
[UIView setAnimationDuration:animationDuration];
float width = self.view.frame.size.width;
float height = self.view.frame.size.height;
if(offset > 0)
{
CGRect rect = CGRectMake(0.0f, -offset,width,height);
self.view.frame = rect;
}
[UIView commitAnimations];
}
//屏幕恢复原样
-(void)textFieldDidEndEditing:(UITextField *)textField
{
//滑动效果
NSTimeInterval animationDuration = 0.30f;
[UIView beginAnimations:@"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
//恢复屏幕
self.view.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height);//64-216
[UIView commitAnimations];
}
//return返回
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.contentView endEditing:YES];
return YES;
}
判断是否为正确的手机号码
#pragma mark - 判断用户输入的手机号码是否正确
- (BOOL)isMobileNumber:(NSString *)mobileNum {
// 电信号段:133/153/180/181/189/177
// 联通号段:130/131/132/155/156/185/186/145/176
// 移动号段:134/135/136/137/138/139/150/151/152/157/158/159/182/183/184/187/188/147/178
// 虚拟运营商:170
NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[06-8])\\d{8}$";
NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
return [regextestmobile evaluateWithObject:mobileNum];
}
/*
case let .email(str):
predicateStr = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
currObject = str
case let .phoneNum(str):
predicateStr = "^((13[0-9])|(15[^4,\\D]) |(17[0,0-9])|(18[0,0-9]))\\d{8}$"
currObject = str
case let .carNum(str):
predicateStr = "^[A-Za-z]{1}[A-Za-z_0-9]{5}$"
currObject = str
case let .username(str):
predicateStr = "^[A-Za-z0-9]{6,20}+$"
currObject = str
case let .password(str):
predicateStr = "^[a-zA-Z0-9]{6,20}+$"
currObject = str
case let .nickname(str):
predicateStr = "^[\\u4e00-\\u9fa5]{4,8}$"
currObject = str
case let .URL(str):
predicateStr = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$"
currObject = str
case let .IP(str):
predicateStr = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
currObject = str
}
*/
判断当前版本号
业务逻辑:从服务器获得最新的版本号和是否要强制更新的字段,当用户版本与服务器版本不同时,弹出警告框让用户更新,若用户点击确定则跳转到appStore下载,点击取消则判断服务器返回的强制更新字段是否有值,有则关闭app不让用户使用(当后台接口改变时会出现这种情况)
#pragma mark - 判断版本号
- (void)getVersion{
//通过发送网络请求从服务器上获取最新版本号
[manager GET:kGetVersion parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *responseObject) {
//得到服务器版本
NSString *updataVersion = responseObject[@"currVesion"];
//获取当前设备中应用的版本号
NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
NSString *currentVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
//判断两个版本是否相同
if ([updataVersion compare:currentVersion options:NSNumericSearch] == NSOrderedDescending) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"更新" message:@"您当前版本过低,请更新" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *update = [UIAlertAction actionWithTitle:@"更新" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//跳转到响应地址进行更新
//appID根据上传的应用取得
NSString *appID = @"114XXXXXXX";
NSString *appUrl = @"http://itunes.apple.com/lookup?id=";
NSString *urlStr = [NSString stringWithFormat:@"%@%@", appUrl, appID];
NSURL *url = [NSURL URLWithString:urlStr];
// NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@",infoDict[@"currVesionDetail"]]];
[[UIApplication sharedApplication] openURL:url];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//判断是否要强制更新
if (responseObject[@"checkVesion"]) {
//说明要强制更新,则杀死程序
UIApplication *app = [UIApplication sharedApplication];
UIWindow *window = app.keyWindow;
[UIView animateWithDuration:1.0f animations:^{
window.alpha = 0;
window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
} completion:^(BOOL finished) {
exit(0);
}];
//exit(0);
}
}];
[alert addAction:update];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
}
使用SDWebImage当收到内存警告时清除缓存
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
SDWebImageManager *mrg = [SDWebImageManager sharedManager];
//1,取消下砸操作
[mrg cancelAll];
//2,清除内存缓存
[mrg.imageCache clearMemory];
}
KVO模式监听数组的变化
- (void)viewDidLoad{
....
[self addObserver:self forKeyPath:@"array" options:NSKeyValueObservingOptionNew context:nil];
...
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
//实现监听方法
}
这样监听是无效的,必须要实现以下方法
//注意,方法名中inArrayAtIndex,其中Array要根据属性名和改变
-(void)insertObject:(id)object inArrayAtIndex:(NSUInteger)index{
//向数组中插入数据
[self.array insertObject:object atIndex:index];
}
-(void)removeObjectFromArrayAtIndex:(NSUInteger)index{
//向数组中删除数据
[self.array removeObjectAtIndex:index];
}
当要往数组上增加/删除数据,要通过上面两个方法,而不是直接使用self.array addObject:
添加
更多方法如下
-(void)insertArray:(NSArray *)array atIndexes:(NSIndexSet *)indexes{}
-(void)removeArrayAtIndexes:(NSIndexSet *)indexes{}
-(void)replaceArrayAtIndexes:(NSIndexSet*)indexes withArray:(NSArray *)array{}
-(void)replaceObjectInArrayAtIndex:(NSUInteger)index withObject:(id)object{}
ScrollView及其子类下拉放大头部图片
原理:让ScrollView顶部缩进要放的headerView的高度,在拖动ScrollView时,保持headerView的y始终在原位,而高度加上偏移值
- (void)viewDidLoad {
...
//设置tableView的缩进
tableView.contentInset = UIEdgeInsetsMake(headerViewHeight, 0, 0, 0);
//设置headerView
imageView.frame = CGRectMake(0, -headerViewHeight, self.view.frame.size.width, headerViewHeight);
imageView.contentMode = UIViewContentModeScaleAspectFill;
//将imageView插入到tableView的最上层,盖住空白处
[self.tableView insertSubview:imageView atIndex:0];
...
}
#pragma mark - delegate
//偏移改变headerView大小
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat y = scrollView.contentOffset.y ; //如果有导航栏则要加上64
if (y< -headerViewHeight) {
CGRect frame = self.headerView.frame;
frame.origin.y = y;
frame.size.height = -y;
self.headerView.frame = frame;
}
}