在实际的开发中掌握一些小的开发技巧,往往会让你的开发效率显著提升。下面是我自己总结的一些小的开发技巧,希望对感兴趣的小伙伴有些帮助。
1.在开发中判断字符串是否为空的正确姿势
// IOS 开发中判断字符串是否为空字符的方法
- (BOOL)isBlankString:(id)string {
if (!string)
{
return YES;
}
if ([string isKindOfClass:[NSNull class]])
{
return YES;
}
if ([string isKindOfClass:[NSString class]] && [string isEqualToString:@"(null)"])
{
return YES;
}
if ([string isKindOfClass:[NSString class]] && [string isEqualToString:@""])
{
return YES;
}
if ([string isKindOfClass:[NSString class]] && [string length]==0)
{
return YES;
}
if ([string isKindOfClass:[NSString class]] && [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0)
{
return YES;
}
return NO;
}
2.在Xcode工程中创建多个target
在实际的项目里往往需要配置不同的开发环境(分别是:生产环境、测试环境、开发环境),每次项目进行环境切换的时候,对应的修改各种配置会十分麻烦,如果在项目里创建多个target分别是:生产环境、测试环境、开发环境),每个target对应一个环境,并配置不同的info.plist文件,这样做的好处是不用开发人员每次都要去手动开启/注释某些代码去发布,而是先配置好,到时候直接切换target就可以打包上线了。
下面是图文教程
第一步:
第二步:
第三步:
第四步:
第五步:
第六步:
第七步:
第八步:
最后一步: 在项目配置文件中。配置对应的宏定义就能实现切换不同的target,实现不同的环境配置。
附上github中的对应链接
3.如何快速的查看一段代码的执行时间。
#define StartTime NSDate *startTime = [NSDate date]
#define EndTime NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])
在想要查看执行时间的代码的地方进行这么处理
StartTime
//do your work here
EndTime
4.判断一个类的实例是不是某类的子类或就是某类,使用isKindOfClass。
假如类B继承于类A,如下:
B *objB = [[B alloc] init];
BOOL rev = [objB inKindOfClass:[A class]]; //判断实例对象objB是否是类A的子类或就是类A
//如果rev=YES则表示实例对象objB是类A的子类或类A
BOOL rev = [objB isMemberOfClass:[A class]]; //判断实例对象objB是否是类A,结果rev=NO
BOOL rev = [objB isMemberOfClass:[B class]]; //判断实例对象objB是否是类B,结果rev=YES
//isSubclassOfClass等同于inKindOfClass,是判断一个类是否是某类的子类或就是某类,但它是类方法,适用于类间判断
BOOL rev = [B isSubclassOfClass:[A class]]; //判断类B是否是类A的子类或就是类A,结果rev=YES
BOOL rev = [B isSubclassOfClass:[B class]]; //判断类B是否是类A的子类或就是类A,结果rev=YES
5.判断一个类是否是UIWindow的rootViewController
方式一:
UIViewController *vc = self.window.rootViewController;
//判断如果是在登录页面,那么不进行跳转
if ([vc isKindOfClass:[LoginViewController class]]) {
return;
}
方式二:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
if ([window.rootViewController isKindOfClass:[LoginViewController class]]) {
return;
}
6.删除所有NSUserDefaults记录
//方法一
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
//方法二
- (void)resetDefaults
{
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary * dict = [defs dictionaryRepresentation];
for (id key in dict)
{
[defs removeObjectForKey:key];
}
[defs synchronize];
}
7.获取某个view所在的控制器
- (UIViewController *)viewController
{
UIViewController *viewController = nil;
UIResponder *next = self.nextResponder;
while (next)
{
if ([next isKindOfClass:[UIViewController class]])
{
viewController = (UIViewController *)next;
break;
}
next = next.nextResponder;
}
return viewController;
}
8.获取图片某一点的颜色
- (UIColor*) getPixelColorAtLocation:(CGPoint)point inImage:(UIImage *)image
{
UIColor* color = nil;
CGImageRef inImage = image.CGImage;
CGContextRef cgctx = [self createARGBBitmapContextFromImage:inImage];
if (cgctx == NULL) {
return nil; /* error */
}
size_t w = CGImageGetWidth(inImage);
size_t h = CGImageGetHeight(inImage);
CGRect rect = {{0,0},{w,h}};
CGContextDrawImage(cgctx, rect, inImage);
unsigned char* data = CGBitmapContextGetData (cgctx);
if (data != NULL) {
int offset = 4*((w*round(point.y))+round(point.x));
int alpha = data[offset];
int red = data[offset+1];
int green = data[offset+2];
int blue = data[offset+3];
color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:
(blue/255.0f) alpha:(alpha/255.0f)];
}
CGContextRelease(cgctx);
if (data) {
free(data);
}
return color;
}
9.禁止锁屏
默认情况下,当设备一段时间没有触控动作时,ios会锁住屏幕。但有一些应用是不需要锁屏的,比如视频播放器。
[UIApplication sharedApplication].idleTimerDisabled = YES;
或
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
10.手动更改iOS状态栏的颜色
- (void)setStatusBarBackgroundColor:(UIColor *)color
{
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)])
{
statusBar.backgroundColor = color;
}
}
11.判断当前ViewController是push还是present的方式显示的
NSArray *viewcontrollers=self.navigationController.viewControllers;
if (viewcontrollers.count > 1)
{
if ([viewcontrollers objectAtIndex:viewcontrollers.count - 1] == self)
{
//push方式
[self.navigationController popViewControllerAnimated:YES];
}
}
else
{
//present方式
[self dismissViewControllerAnimated:YES completion:nil];
}
12.修改UITextField中Placeholder的文字颜色
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
修改UITextField中Placeholder的文字大小
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
13.CocoaPods pod install/pod update更新慢的问题
pod install --verbose --no-repo-update
pod update --verbose --no-repo-update
//如果不加后面的参数,默认会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少
14.GCD timer定时器
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(timer, ^{
//@"倒计时结束,关闭"
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
});
});
dispatch_resume(timer);
15.图片上绘制文字 写一个UIImage的category
- (UIImage *)imageWithTitle:(NSString *)title fontSize:(CGFloat)fontSize
{
//画布大小
CGSize size=CGSizeMake(self.size.width,self.size.height);
//创建一个基于位图的上下文
UIGraphicsBeginImageContextWithOptions(size,NO,0.0);//opaque:NO scale:0.0
[self drawAtPoint:CGPointMake(0.0,0.0)];
//文字居中显示在画布上
NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
paragraphStyle.alignment=NSTextAlignmentCenter;//文字居中
//计算文字所占的size,文字居中显示在画布上
CGSize sizeText=[title boundingRectWithSize:self.size options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}context:nil].size;
CGFloat width = self.size.width;
CGFloat height = self.size.height;
CGRect rect = CGRectMake((width-sizeText.width)/2, (height-sizeText.height)/2, sizeText.width, sizeText.height);
//绘制文字
[title drawInRect:rect withAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:fontSize],NSForegroundColorAttributeName:[ UIColor whiteColor],NSParagraphStyleAttributeName:paragraphStyle}];
//返回绘制的新图形
UIImage *newImage= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
16查找一个视图的所有子视图
- (NSMutableArray *)allSubViewsForView:(UIView *)view
{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];
for (UIView *subView in view.subviews)
{
[array addObject:subView];
if (subView.subviews.count > 0)
{
[array addObjectsFromArray:[self allSubViewsForView:subView]];
}
}
return array;
}
17.UIView设置部分圆角
你是不是也遇到过这样的问题,一个button或者label,只要右边的两个角圆角,或者只要一个圆角。该怎么办呢。这就需要图层蒙版来帮助我们了
CGRect rect = view.bounds;
CGSize radio = CGSizeMake(30, 30);//圆角尺寸
UIRectCorner corner = UIRectCornerTopLeft|UIRectCornerTopRight;//这只圆角位置
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corner cornerRadii:radio];
CAShapeLayer *masklayer = [[CAShapeLayer alloc]init];//创建shapelayer
masklayer.frame = view.bounds;
masklayer.path = path.CGPath;//设置路径
view.layer.mask = masklayer;
18.给UIView设置图片
UIImage *image = [UIImage imageNamed:@"image"];
self.MYView.layer.contents = (__bridge id _Nullable)(image.CGImage);
self.MYView.layer.contentsRect = CGRectMake(0, 0, 0.5, 0.5);
19.去掉导航栏返回的back标题
[[UIBarButtonItemappearance]setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)forBarMetrics:UIBarMetricsDefault];
20.防止scrollView手势覆盖侧滑手势
[scrollView.panGestureRecognizerrequireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
21.dispatch_group的使用(多请求同时进行)
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_enter(dispatchGroup);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"第一个请求完成");
dispatch_group_leave(dispatchGroup);
});
dispatch_group_enter(dispatchGroup);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"第二个请求完成");
dispatch_group_leave(dispatchGroup);
});
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
NSLog(@"请求完成");
});
22.UITableView的Group样式下顶部空白处理
//分组列表头部空白处理
_messageTable.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
_messageTable.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
23、UITableView收起键盘何必这么麻烦 一个属性搞定,效果好(UIScrollView同样可以使用
yourTableViewName.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
24、去除UItableView的Header粘滞效果
//去除UItableView的Header粘滞效果
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.mineTableView) {
CGFloat sectionHeaderHeight = 20;
if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y >= sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
}
25、通过LaunchScreen.storyBoard设置启动页
通过LaunchScreen.storyBoard设置启动页开始的时候,图片放到Assets.xcassets中,总是白屏,后来将图片放置到图片images文件夹中,就可以正常展示了。