开发中总有那么些小的细节让我们事半功倍,下面我就列一列,希望帮到你,哈哈。
1、禁止手机睡眠
[UIApplication sharedApplication].idleTimerDisabled = YES;
2、隐藏某行cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 如果是你需要隐藏的那一行,返回高度为0
if(indexPath.row == YouWantToHideRow)
return 0;
return 44;
}
// 然后再你需要隐藏cell的时候调用
[self.tableView beginUpdates];
[self.tableView endUpdates];
3、cocoa pods 出现ERROR: While executing gem ... (Errno::EPERM)
解决办法
4、动画切换window的根控制器
// options是动画选项
[UIView transitionWithView:[UIApplication sharedApplication].keyWindow duration:0.5f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[UIApplication sharedApplication].keyWindow.rootViewController = [RootViewController new];
[UIView setAnimationsEnabled:oldState];
} completion:^(BOOL finished) {
}];
5、去除数组中重复的对象
NSArray *newArr = [oldArr valueForKeyPath:@"distinctUnionOfObjects.self"];
6、跳进app权限设置
// 跳进app设置
if (UIApplicationOpenSettingsURLString != NULL) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];
}
7、给一个view截图
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
8、通知宏
#define NOTIF_ADD(n, f) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(f) name:n object:nil]
#define NOTIF_POST(n, o) [[NSNotificationCenter defaultCenter] postNotificationName:n object:o]
#define NOTIF_REMV() [[NSNotificationCenter defaultCenter] removeObserver:self]
9、获取window
+(UIWindow*)getWindow {
UIWindow* win = nil; //[UIApplication sharedApplication].keyWindow;
for (id item in [UIApplication sharedApplication].windows) {
if ([item class] == [UIWindow class]) {
if (!((UIWindow*)item).hidden) {
win = item;
break;
}
}
}
return win;
}
10、修改textField的placeholder的字体颜色和字体大小
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
[textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
11、获取app缓存大小
- (CGFloat)getCachSize {
NSUInteger imageCacheSize = [[SDImageCache sharedImageCache] getSize];
//获取自定义缓存大小
//用枚举器遍历 一个文件夹的内容
//1.获取 文件夹枚举器
NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:myCachePath];
__block NSUInteger count = 0;
//2.遍历
for (NSString *fileName in enumerator) {
NSString *path = [myCachePath stringByAppendingPathComponent:fileName];
NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
count += fileDict.fileSize;//自定义所有缓存大小
}
// 得到是字节 转化为M
CGFloat totalSize = ((CGFloat)imageCacheSize+count)/1024/1024;
return totalSize;
}
12、清理app缓存
- (void)handleClearView {
//删除两部分
//1.删除 sd 图片缓存
//先清除内存中的图片缓存
[[SDImageCache sharedImageCache] clearMemory];
//清除磁盘的缓存
[[SDImageCache sharedImageCache] clearDisk];
//2.删除自己缓存
NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
[[NSFileManager defaultManager] removeItemAtPath:myCachePath error:nil];
}
13、获取手机型号
+ (NSString *)getDeviceInfo {
struct utsname systemInfo;
uname(&systemInfo);
NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([platform isEqualToString:@"iPhone9,1"]) return @"国行、日版、港行iPhone 7";
if ([platform isEqualToString:@"iPhone9,2"]) return @"港行、国行iPhone 7 Plus";
if ([platform isEqualToString:@"iPhone9,3"]) return @"美版、台版iPhone 7";
if ([platform isEqualToString:@"iPhone9,4"]) return @"美版、台版iPhone 7 Plus";
if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G";
if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2";
if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2";
if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2";
if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G";
if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G";
if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G";
if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3";
if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3";
if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3";
if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4";
if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4";
if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4";
if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air";
if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air";
if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air";
if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G";
if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G";
if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G";
if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
if ([platform isEqualToString:@"x86_64"]) return @"iPhone Simulator";
return platform;
}
14、判断图片类型
//通过图片Data数据第一个字节 来获取图片扩展名
- (NSString *)contentTypeForImageData:(NSData *)data
{
uint8_t c;
[data getBytes:&c length:1];
switch (c)
{
case 0xFF:
return @"jpeg";
case 0x89:
return @"png";
case 0x47:
return @"gif";
case 0x49:
case 0x4D:
return @"tiff";
case 0x52:
if ([data length] < 12) {
return nil;
}
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"]
&& [testString hasSuffix:@"WEBP"])
{
return @"webp";
}
return nil;
}
return nil;
}
15、获取手机和app信息
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
// app名称
NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
NSLog(@"app名称: %@", app_Name);
// app版本
NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
NSLog(@"app版本: %@", app_Version);
// app build版本
NSString *app_build = [infoDictionary objectForKey:@"CFBundleVersion"];
NSLog(@"app build版本: %@", app_build);
//手机别名: 用户定义的名称
NSString* userPhoneName = [[UIDevice currentDevice] name];
NSLog(@"手机别名: %@", userPhoneName);
//设备名称
NSString* deviceName = [[UIDevice currentDevice] systemName];
NSLog(@"设备名称: %@",deviceName );
//手机系统版本
NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
NSLog(@"手机系统版本: %@", phoneVersion);
//手机型号
NSString* phoneModel = [[UIDevice currentDevice] model];
NSLog(@"手机型号: %@",phoneModel );
//地方型号 (国际化区域名称)
NSString* localPhoneModel = [[UIDevice currentDevice] localizedModel];
NSLog(@"国际化区域名称: %@",localPhoneModel );
// 当前应用名称
NSString *appCurName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
NSLog(@"当前应用名称:%@",appCurName);
// 当前应用软件版本 比如:1.0.1
NSString *appCurVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
NSLog(@"当前应用软件版本:%@",appCurVersion);
// 当前应用版本号码 int类型
NSString *appCurVersionNum = [infoDictionary objectForKey:@"CFBundleVersion"];
NSLog(@"当前应用版本号码:%@",appCurVersionNum);
16、圆形图片
- (instancetype)circleImage
{
// 开启图形上下文
UIGraphicsBeginImageContext(self.size);
// 获得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 矩形框
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
// 添加一个圆
CGContextAddEllipseInRect(ctx, rect);
// 裁剪(裁剪成刚才添加的图形形状)
CGContextClip(ctx);
// 往圆上面画一张图片
[self drawInRect:rect];
// 获得上下文中的图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图形上下文
UIGraphicsEndImageContext();
return image;
}
17、验证身份证号
- (BOOL)validateIdentityCard {
BOOL flag;
if (self.length <= 0) {
flag = NO;
return flag;
}
NSString *regex2 = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
return [identityCardPredicate evaluateWithObject:self];
}
18、给imageView添加倒影
CGRect frame = self.frame;
frame.origin.y += (frame.size.height + 1);
UIImageView *reflectionImageView = [[UIImageView alloc] initWithFrame:frame];
self.clipsToBounds = TRUE;
reflectionImageView.contentMode = self.contentMode;
[reflectionImageView setImage:self.image];
reflectionImageView.transform = CGAffineTransformMakeScale(1.0, -1.0);
CALayer *reflectionLayer = [reflectionImageView layer];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.bounds = reflectionLayer.bounds;
gradientLayer.position = CGPointMake(reflectionLayer.bounds.size.width / 2, reflectionLayer.bounds.size.height * 0.5);
gradientLayer.colors = [NSArray arrayWithObjects:
(id)[[UIColor clearColor] CGColor],
(id)[[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.3] CGColor], nil];
gradientLayer.startPoint = CGPointMake(0.5,0.5);
gradientLayer.endPoint = CGPointMake(0.5,1.0);
reflectionLayer.mask = gradientLayer;
[self.superview addSubview:reflectionImageView];
19、让label的文字内容显示在左上/右上/左下/右下/中心顶/中心底部
// 自定义UILabel 重写label的textRectForBounds方法
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
CGRect rect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
switch (self.textAlignmentType) {
case WZBTextAlignmentTypeLeftTop: {
rect.origin = bounds.origin;
}
break;
case WZBTextAlignmentTypeRightTop: {
rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, bounds.origin.y);
}
break;
case WZBTextAlignmentTypeLeftBottom: {
rect.origin = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds) - rect.size.height);
}
break;
case WZBTextAlignmentTypeRightBottom: {
rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, CGRectGetMaxY(bounds) - rect.size.height);
}
break;
case WZBTextAlignmentTypeTopCenter: {
rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - rect.origin.y);
}
break;
case WZBTextAlignmentTypeBottomCenter: {
rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - CGRectGetMaxY(bounds) - rect.size.height);
}
break;
case WZBTextAlignmentTypeLeft: {
rect.origin = CGPointMake(0, rect.origin.y);
}
break;
case WZBTextAlignmentTypeRight: {
rect.origin = CGPointMake(rect.origin.x, 0);
}
break;
case WZBTextAlignmentTypeCenter: {
rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, (CGRectGetHeight(bounds) - CGRectGetHeight(rect)) / 2);
}
break;
default:
break;
}
return rect;
}
- (void)drawTextInRect:(CGRect)rect {
CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines];
[super drawTextInRect:textRect];
}
20、移除字符串中的空格和换行
+ (NSString *)removeSpaceAndNewline:(NSString *)str {
NSString *temp = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
temp = [temp stringByReplacingOccurrencesOfString:@"\r" withString:@""];
temp = [temp stringByReplacingOccurrencesOfString:@"\n" withString:@""];
return temp;
}
//待处理的字符串
NSString *string = @" A B CD EFG\n MN\n";
//去除两端空格和回车(注意是两端),处理后的string1 = @"A B CD EFG\n MN";
NSString *string1 = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
21、获取视频的第一帧图片
NSURL *url = [NSURL URLWithString:filepath];
AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generate1.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 2);
CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *one = [[UIImage alloc] initWithCGImage:oneRef];
return one;
22、删除UIButton的所有点击事件
[testButton removeTarget:nil action:nil forControlEvents:UIControlEventAllEvents];
23、删除某个view所有的子视图
[[self.view subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
24、layoutSubviews方法什么时候调用?
- 1.init方法不会调用
- 2.addSubview方法等时候会调用
- 3.bounds改变的时候调用
- 4.scrollView滚动的时候会调用scrollView的layoutSubviews方法(所以不建议在scrollView的layoutSubviews方法中做复杂逻辑)
- 5.旋转设备的时候调用
- 6.子视图被移除的时候调用
25、tableViewCell分割线顶到头
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cell setSeparatorInset:UIEdgeInsetsZero];
[cell setLayoutMargins:UIEdgeInsetsZero];
cell.preservesSuperviewLayoutMargins = NO;
}
- (void)viewDidLayoutSubviews {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
26、UITextView中打开或禁用复制,剪切,选择,全选等功能
// 继承UITextView重写这个方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 返回NO为禁用,YES为开启
// 粘贴
if (action == @selector(paste:)) return NO;
// 剪切
if (action == @selector(cut:)) return NO;
// 复制
if (action == @selector(copy:)) return NO;
// 选择
if (action == @selector(select:)) return NO;
// 选中全部
if (action == @selector(selectAll:)) return NO;
// 删除
if (action == @selector(delete:)) return NO;
// 分享
if (action == @selector(share)) return NO;
return [super canPerformAction:action withSender:sender];
}
27、字符串反转
//第一种:
- (NSString *)reverseWordsInString:(NSString *)str
{
NSMutableString *newString = [[NSMutableString alloc] initWithCapacity:str.length];
for (NSInteger i = str.length - 1; i >= 0 ; i --)
{
unichar ch = [str characterAtIndex:i];
[newString appendFormat:@"%c", ch];
}
return newString;
}
//第二种:
- (NSString*)reverseWordsInString:(NSString*)str
{
NSMutableString *reverString = [NSMutableString stringWithCapacity:str.length];
[str enumerateSubstringsInRange:NSMakeRange(0, str.length) options:NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[reverString appendString:substring];
}];
return reverString;
}
28、手动更改iOS状态栏的颜色
- (void)setStatusBarBackgroundColor:(UIColor *)color
{
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)])
{
statusBar.backgroundColor = color;
}
}
29、UIView设置部分圆角(左上,右上,左下,右下)
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;
30、获取到webview的高度
CGFloat height = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] floatValue];
31、UIWebView设置User-Agent
//设置
NSDictionary *dic = @{@"UserAgent":@"your UserAgent"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dic];
//获取
NSString *agent = [self.WebView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
32、UIWebView里面的图片自适应屏幕(在webView加载完的代理方法里面写)
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *js = @"function imgAutoFit() { \
var imgs = document.getElementsByTagName('img'); \
for (var i = 0; i ( imgs.length; ++i) { \
var img = imgs[i]; \
img.style.maxWidth = %f; \
} \
}";
js = [NSString stringWithFormat:js, [UIScreen mainScreen].bounds.size.width - 20];
[webView stringByEvaluatingJavaScriptFromString:js];
[webView stringByEvaluatingJavaScriptFromString:@"imgAutoFit()"];
}
33、获取webview的内容高度
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//通过JS代码获取webview的内容高度
CGFloat height = [[self.infoWebView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue];
}
34、快速定位僵尸对象
iOS中把那些已经release但还没完全消失的对象叫做僵尸对象,对已经release的对象再次释放,就会发生异常。虽然自从使用ARC后,由于对象释放产生的异常已经大大变少,但偶尔还会出现。开启僵尸对象模式后,就能快速定位到异常位置。开启方式如下:Product-->Scheme-->Edit Scheme. 勾选Enable Zombie Objects即可。
35、Label加中划线
//方法一:直接赋值富文本
UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 50)];
[self.view addSubview:label];
label.text = @"59.00";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor grayColor];
NSMutableAttributedString *newPrice = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"¥%@",label.text]];
[newPrice addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, newPrice.length)];
label.attributedText = newPrice;
//方法二:子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect{
[super drawTextInRect:rect];
NSDictionary *fontdic = [NSDictionary dictionaryWithObjectsAndKeys:[self font],NSFontAttributeName, nil];
CGSize size = [[self text] sizeWithAttributes:fontdic];
CGFloat strikeWidth = size.width;
CGRect lineRect;
if ([self textAlignment] == NSTextAlignmentRight) {
lineRect = CGRectMake(rect.size.width - strikeWidth, rect.size.height/2, strikeWidth, 1);
} else if ([self textAlignment] == NSTextAlignmentCenter) {
lineRect = CGRectMake(rect.size.width/2 - strikeWidth/2, rect.size.height/2, strikeWidth, 1);
} else {
lineRect = CGRectMake(0, rect.size.height/2, strikeWidth, 1);
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextFillRect(context, lineRect);
}
36、不要离屏渲染画圆角
有很多做圆角的方式,最简单的就是设置label.layer.cornerRadius = 2; label.layer.masksToBounds = YES; 但是这样做 if(label.layer.cornerRadius > 0 && label.layer.masksToBounds = YES)会出现离屏渲染,对于页面中只有少量需要做圆角,不会造成卡顿;但是如果是每个Cell都设置多个圆角,就会使列表滑动起来有明显卡顿。
//第一种--只要边框不要背景色
直接设置cornerRadius,不需要设置masksToBounds = YES,就可以实现圆角功能。
//第二种--同时设置label的backgroundColor时
label.layer.backgroundColor = [UIColor redColor].CGColor;
label.layer.cornerRadius = 2;
37、准确判断 WebView 加载完成
当网页重定向发生时,网址被重定向几次,WebViewDidFinishLoad 就会被调用几次。所以如果你只想在最后加载完成时调用某些代码,可以通过webView.isLoading来判断。当 WebViewDidFinishLoad 时如果 webView.isLoading == YES 那么说明网页可能发生了重定向。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if (!webView.isLoading) {
[self webViewDidFinishLoadCompletely];
}
}
38、获取webView高度
// 对webView中的scrollView设置KVO
[_webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
// KVO具体实现
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentSize"]) {
// 这两个JS代码都可以计算出webview的高度
// document.documentElement.scrollHeight
// document.body.offsetHeight
[_webView evaluateJavaScript:@"document.body.offsetHeight" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
// 加20像素是为了预留出边缘,这里可以随意
CGFloat height = [result doubleValue] + 20;
_webHeight = height;
_webView.frame = CGRectMake(0, 0, kScreenWidth, height);
}];
}
}
// 别忘注销kvo
- (void)dealloc
{
[_webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
}
39、禁用emoji
- (NSString *)disable_emoji:(NSString *)text
{
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]" options:NSRegularExpressionCaseInsensitive error:nil];
NSString *modifiedString = [regex stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:@""];
return modifiedString;
}
40、使用第三方键盘,通知监听事件执行多次的解决方法
偶然发现在使用搜狗第三方键盘时候,有些卡顿。
打断点发现:键盘弹出的时候,UIKeyboardWillShowNotification,这个通知监听的方法居然进了3次,而且监听到的键盘高度居然不一致。
最终的解决方法:
#pragma mark - 键盘通知的方法
-(void)keyboardWillShow:(NSNotification *)notification{
NSDictionary *keyBordInfo = [notification userInfo];
DDLog(@"keyBordInfo = %@",keyBordInfo);
NSValue *value = [keyBordInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyBoardRect = [value CGRectValue];
float height = keyBoardRect.size.height;
CGRect beginRect = [[keyBordInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect endRect = [[keyBordInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
DDLog(@"keyBordInfo.height = %f",height);
// 第三方键盘回调三次问题,监听仅执行最后一次
if(beginRect.size.height > 0 && (beginRect.origin.y - endRect.origin.y > 0)){
//do someing
}
}
41、UIAlertController颜色字号更改
NSMutableAttributedString *attTitle = [[NSMutableAttributedString alloc]initWithString:@"标题1" attributes:@{NSForegroundColorAttributeName:[UIColor blueColor],NSFontAttributeName:[UIFont systemFontOfSize:17]}];
NSMutableAttributedString *attMessage = [[NSMutableAttributedString alloc]initWithString:@"message" attributes:@{NSForegroundColorAttributeName:[UIColor purpleColor],NSFontAttributeName:[UIFont systemFontOfSize:14]}];
UIAlertController *action = [UIAlertController alertControllerWithTitle:@"标题1" message:@"message" preferredStyle:UIAlertControllerStyleActionSheet];
[action setValue:attTitle forKey:@"attributedTitle"];
[action setValue:attMessage forKey:@"attributedMessage"];
UIAlertAction *alert1 = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self loadCamera];
}];
[alert1 setValue:[UIColor cyanColor] forKey:@"titleTextColor"];
[action addAction:alert1];
UIAlertAction *alert2 = [UIAlertAction actionWithTitle:@"从相册选择照片" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self loadPhotoLibraryPhoto];
}];
[alert2 setValue:[UIColor brownColor] forKey:@"titleTextColor"];
[action addAction:alert2];
UIAlertAction *cancelAlert = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[cancelAlert setValue:[UIColor redColor] forKey:@"titleTextColor"];
[action addAction:cancelAlert];
[self presentViewController:action animated:YES completion:nil];
42、UILabel下划线
UILabel *testLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 120, 200, 30)];
testLabel.backgroundColor = [UIColor lightGrayColor];
testLabel.textAlignment = NSTextAlignmentCenter;
NSString *cstrTitle = @"This is an attributed string.下划线";
NSDictionary *attribtDic = @{NSUnderlineStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle]};
NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc]initWithString:cstrTitle attributes:attribtDic];
testLabel.attributedText = attribtStr;
[self.view addSubview:testLabel];
43、UITextView中打开或禁用复制,剪切,选择,全选等功能
// 子类化UITextView重写下面方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 返回NO为禁用,YES为开启
// 粘贴
if (action == @selector(paste:)) return NO;
// 剪切
if (action == @selector(cut:)) return NO;
// 复制
if (action == @selector(copy:)) return NO;
// 选择
if (action == @selector(select:)) return NO;
// 选中全部
if (action == @selector(selectAll:)) return NO;
// 删除
if (action == @selector(delete:)) return NO;
// 分享
if (action == @selector(share)) return NO;
return [super canPerformAction:action withSender:sender];
}
44、view添加虚线边框
CAShapeLayer *border = [CAShapeLayer layer];
border.strokeColor = [UIColor colorWithRed:67/255.0f green:37/255.0f blue:83/255.0f alpha:1].CGColor;
border.fillColor = nil;
border.lineDashPattern = @[@4, @2];
border.path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
border.frame = view.bounds;
[view.layer addSublayer:border];
45、UIImage和base64互转
- (NSString *)encodeToBase64String:(UIImage *)image {
return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [UIImage imageWithData:data];
}
46、为什么@property声明(NString,NSArray,NSDictionary)时需要使用copy,使用strong有什么问题
- 因为NString,NSArray,NSDictionary都有自己对应的子类:NSMutableString,NSMutableArray,NSMutableDictionary,而父类指针可以指向子类对象,使用copy可以让本对象不受外界(子对象)影响,无论给我传入的是一个可变对象还是一个不可变对象,都能保证自身持有的是一个不可变副本。
- 使用strong时,如果这个属性指向一个可变对象,修改可变对象时,这个属性值也会被修改。
47、app新功能半透明蒙层引导
-
mask属性按照我的理解就是显示maskLayer与父layer非透明部分的交集,所以中间的没有path的透明部分就不显示了。
-
代码实现,self就是占整个屏幕的黑色蒙层,这里的bezierPathByReversingPath可以生成反向的path,frame是需要透明显示的位置
UIBezierPath *path = [UIBezierPath bezierPathWithRect:kScreen_BOUNDS];
[path appendPath: [[UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:4] bezierPathByReversingPath]];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = path.CGPath;
self.layer.mask = shapeLayer;
48、UILabel显示不同颜色字体和行间距
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:label.text];
//行间距
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:20];
[attrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, label.text.length)];
//不同颜色
[string addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0,5)];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(5,6)];
[string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(11,5)];
label.attributedText = attrString;
49、防止离屏渲染为image添加圆角
// image分类
-(UIImage *)circleImage
{
// NO代表透明
UIGraphicsBeginImageContextWithOptions(self.size, NO, 1);
// 获得上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 添加一个圆
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
// 方形变圆形
CGContextAddEllipseInRect(ctx, rect);
// 裁剪
CGContextClip(ctx);
// 将图片画上去
[self drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
50、判断一个字符串是否为数字
NSString *testString = @"123wo";
NSCharacterSet *notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([testString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// 是数字
} else
{
// 不是数字
}
51、获取当前导航控制器下前一个控制器
-(UIViewController *)backViewController
{
NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];
if ( myIndex != 0 && myIndex != NSNotFound ) {
return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
} else {
return nil;
}
}
52、让导航控制器pop回指定的控制器
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
for (UIViewController *subVC in allViewControllers) {
if ([subVC isKindOfClass:[CommunityViewController class]]) {
[self.navigationController popToViewController:subVC animated:NO];
}
}
53、UIWebView添加单击手势不响应
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(webViewClick)];
tap.delegate = self;
[self.webView addGestureRecognizer:tap];
//因为webView本身有一个单击手势,所以再添加会造成手势冲突,从而不响应。需要绑定手势代理,遵循UIGestureRecognizerDelegate并实现下边的代理方法
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
54、设置UITextField光标位置
//index要设置的光标位置
-(void)cursorLocation:(UITextField *)textField index:(NSInteger)index
{
NSRange range = NSMakeRange(index, 0);
UITextPosition *start = [textField positionFromPosition:[textField beginningOfDocument] offset:range.location];
UITextPosition *end = [textField positionFromPosition:start offset:range.length];
[textField setSelectedTextRange:[textField textRangeFromPosition:start toPosition:end]];
}
55、去除webView黑底
[webView setBackgroundColor:[UIColor clearColor]];
[webView setOpaque:NO];
for (UIView *subView in [webView subviews])
{
if ([subView isKindOfClass:[UIScrollView class]])
{
for (UIView *v2 in subView.subviews)
{
if ([v2 isKindOfClass:[UIImageView class]])
{
v2.hidden = YES;
}
}
}
}
56、解决openUrl延时问题
//方法一
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[application openURL:URL options:@{}
completionHandler:nil];
} else {
[application openURL:URL];
}
});
// 方法二
[self performSelector:@selector(redirectToURL:) withObject:url afterDelay:0.1];
-(void)redirectToURL
{
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[application openURL:URL options:@{}
completionHandler:nil];
} else {
[application openURL:URL];
}
}
57、获取字符串中的数字
-(NSString *)getNumberFromStr:(NSString *)str
{
NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
return [[str componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
}
58、某个界面多个事件同时响应引起的问题
// UIView有个属性叫做exclusiveTouch,设置为YES后,其响应事件会和其他view互斥(有其他view事件响应的时候点击它不起作用)
view.exclusiveTouch = YES;
//一个一个设置太麻烦了,可以全局设置
[[UIView appearance] setExclusiveTouch:YES];
//或者只设置button
[[UIButton appearance] setExclusiveTouch:YES];
59、有的时候一个控制器做为过渡使用,用过之后 push 到下一个页面则不再使用此控制器,如 A -> B -> C, B 是过渡使用的,push 到 C 后即需要将 B 移除出导航栈,以达到可以从 C 直接返回到 A 的目的,其实现依赖 UINavigatioinController 的 setViewControllers: 属性,其实现和使用如下:
//使用分类实现,将自身移除出导航栈
@implementation UIViewController (RemoveFromNavigationStack)
-(void)br_removeFromNavigationControllerStack {
NSMutableArray *newArray = [self.navigationController.viewControllers mutableCopy];
[newArray removeObject:self];
[self.navigationController setViewControllers:newArray animated:YES];
}
@end
//B控制器的实际调用场景
-(void)clickToPushToControllerC:(id)sender {
ControllerC *vc = [[ControllerC alloc] init];
[self.navigationController pushToViewController:vc animated:YES];
[self br_removeFromNavigationControllerStack];
}
60、获取图片扩展名
//通过图片Data数据第一个字节 来获取图片扩展名
- (NSString *)contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"jpeg";
case 0x89:
return @"png";
case 0x47:
return @"gif";
case 0x49:
case 0x4D:
return @"tiff";
case 0x52:
if ([data length] < 12) {
return nil;
}
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
return @"webp";
}
return nil;
}
return nil;
}
61、一般使用SDWebImage 进行图片的显示和缓存,一般缓存的内容比较多了就需要进行清空缓存;清除SDWebImage的内存和硬盘时,可以同时清除session 和 cookie的缓存
// 清理内存
[[SDImageCache sharedImageCache] clearMemory];
// 清理webview 缓存
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
[config.URLCache removeAllCachedResponses];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
// 清理硬盘
[[SDImageCache sharedImageCache] clearDiskOnCompletion:^{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[self.tableView reloadData];
}];
62、UILongPressGestureRecognizer执行2次的问题
//会调用2次,开始时和结束时
- (void)hello:(UILongPressGestureRecognizer *)longPress
{
if (longPress.state == UIGestureRecognizerStateEnded)//需要添加一个判断
{
NSLog(@"long");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"hello"
message:@"Long Press"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alert show];
}
}
63、UITextField 只能输入数字和字母
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textFieldChanged:)
name:UITextFieldTextDidChangeNotification
object:nil];
监听name:UITextFieldTextDidChangeNotification 和 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 来实现。
- (BOOL)validatePasswordString:(NSString *)resultMStr
{
BOOL result = YES;
switch (self.mode) {
case HXSChangePasswordLogin: {
NSString *regex = @"^[a-zA-Z0-9]+$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:resultMStr];
break;
}
case HXSChangePasswordPay: {
NSString *regex = @"^[0-9]+$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
result = [pred evaluateWithObject:resultMStr];
break;
}
}
return result;
}
64、NSArray 快速求总和、平均值、最大值、最小值
NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
NSLog(@"总和=%f\n平均值=%f\n最大值=%f\n最小值=%f",sum,avg,max,min);
65、退出app
- (void)exitApplication{
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
UIWindow *window = app.window;
[UIView animateWithDuration:0.5f animations:^{
window.alpha = 0;
window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
} completion:^(BOOL finished) {
exit(0);
}];
}
66、返回当前星期几
- (NSString*)toWeekString
{
static NSCalendar *calendar;
if (calendar == nil) {
calendar =
[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
}
unsigned unitFlags = NSWeekdayCalendarUnit;
NSDateComponents *comps = [calendar components:unitFlags fromDate:self];
NSArray *weekArr =
[NSArray arrayWithObjects:@"日",@"一",@"二",@"三",@"四",@"五",@"六", nil];
return [NSString stringWithFormat:@"星期%@",
[weekArr objectAtIndex:[comps weekday]-1]];
}
67、把tableview里编辑状态下的cell的勾选的颜色改成别的颜色
self.myTableView.tintColor = [UIColor redColor];
68、iOS Whose view is not in the window hierarchy...
在 一个 ViewController 里面调用另外一个 ViewController
该错误一般是由于在 viewDidLoad 里面调用引起的,解决办法是转移到 viewDidAppear。
69、
网友评论