1、设置导航栏标题的字体颜色和大小
方法一:(自定义视图的方法,一般人也会采用这样的方式)
就是在导航向上添加一个titleView,可以使用一个label,再设置label的背景颜色透明,字体什么的设置就很简单了。
//自定义标题视图 UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 44)]; titleLabel.backgroundColor = [UIColor grayColor]; titleLabel.font = [UIFont boldSystemFontOfSize:20]; titleLabel.textColor = [UIColor greenColor]; titleLabel.textAlignment = NSTextAlignmentCenter; titleLabel.text = @"新闻"; self.navigationItem.titleView = titleLabel;
方法二:(在默认显示的标题中直接修改文件的大小和颜色也是可以的)
[self.navigationController.navigationBar setTitleTextAttributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:19], NSForegroundColorAttributeName:[UIColor redColor] } ]
2、多容器添加同一子控件的bug
[someView addSubView:sbView];
那么在被添加到父视图someView之前,如果sbView已经被otherView加载了,那么上面的代码会先讲sbView从otherView remove掉,在被加载到someView。
所以一个view是不可能同时被2个以上的view加载做子视图的。
3、返回根控制器
- (void)dismissToRootViewController:(UIViewController *)viewController{ if (viewController.presentingViewController == nil) { [viewController.navigationController popToRootViewControllerAnimated:NO]; }else{ UIViewController *vc = viewController.presentingViewController; while (vc.presentingViewController != nil) { vc = vc.presentingViewController; } [vc dismissViewControllerAnimated:NO completion:nil]; } }
4、获取照片拍摄地点信息
- (NSDictionary *)metadata { return self.asset.defaultRepresentation.metadata; } - (CLGeocoder *)geoC { if(!_geoC){ _geoC = [[CLGeocoder alloc] init]; } return _geoC; } - (void)addressInit{ // 获取位置信息 NSDictionary *metadata = [self metadata]; NSDictionary *GPSDict=[metadata objectForKey:(NSString*)kCGImagePropertyGPSDictionary]; // 经纬度 CLLocationDegrees latitude = [[GPSDict objectForKey:@"Latitude"] doubleValue]; CLLocationDegrees longitude = [[GPSDict objectForKey:@"Longitude"] doubleValue]; CLLocation *loc = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude]; WEAKSELF // 反地理编码 [self.geoC reverseGeocodeLocation:loc completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { CLPlacemark *pl = [placemarks firstObject]; if(error == nil){ NSString *str = [NSString stringWithFormat:@"%@%@%@",pl.locality, pl.subLocality, pl.name]; weakSelf.address = str; } else{ weakSelf.address = @""; } }]; }
5、随机数 随机色
Objective-C 中有个arc4random()函数用来生成随机数且不需要种子,
但是这个函数生成的随机数范围比较大,需要用取模的算法对随机值进行限制,有点麻烦。
更方便的随机数函数arc4random_uniform(x),
可以用来产生0~(x-1)范围内的随机数,不需要再进行取模运算。
如果要生成1~x的随机数,可以这么写:arc4random_uniform(x)+1
随机色:
#define random(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0alpha:(a)/255.0] #define randomColor random(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)) [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
6、退出app
AppDelegate *app = [UIApplication sharedApplication].delegate; UIWindow *window = app.window; [UIView animateWithDuration:0.4f animations:^{ window.alpha = 0; CGFloat y = window.bounds.size.height; CGFloat x = window.bounds.size.width / 2; window.frame = CGRectMake(x, y, 0, 0); } completion:^(BOOL finished) { exit(0); }];
7、移除导航条按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd]; button.frame = CGRectMake(0, 0, 30, 30); UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:button]; self.navigationItem.leftBarButtonItem = barButton; #if 0 //第一种 self.navigationItem.leftBarButtonItem = nil; #else //第二种 [self.navigationController.navigationBar.subviews.lastObject setHidden:YES]; #endif
8、隐藏导航栏下划线
// 1)声明UIImageView变量,存储底部横线 @implementation MyViewController { UIImageView *navBarHairlineImageView; } // 2)在viewDidLoad中加入: navBarHairlineImageView = [self findHairlineImageViewUnder:navigationBar] // 3) - (UIImageView *)findHairlineImageViewUnder:(UIView *)view { if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) { return (UIImageView *)view; } for (UIView *subview in view.subviews) { UIImageView *imageView = [self findHairlineImageViewUnder:subview]; if (imageView) { return imageView; } } return nil; } // 最后在viewWillAppear,viewWillDisappear中处理 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; navBarHairlineImageView.hidden = YES; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; navBarHairlineImageView.hidden = NO; } WEAKSELF static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [weakSelf.navigationController.navigationBar.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:NSClassFromString(@"_UIBarBackground")]) { [obj.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[UIImageView class]]) { [obj setHidden:YES]; } }]; } }]; });
9、translucent 与 controller.view
translucent = NO;
translucent = YES;
10、禁用第三方输入法
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString*)extensionPointIdentifier { return NO; }
11、UIView截屏
/* UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); // Render the view [view.layer renderInContext:context]; // Get the image from the context UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext(); // Cleanup the context you created UIGraphicsEndImageContext(); return renderedImage; */ + (UIImage *)snapShotFrom:(UIView *)view{ // 避免frame为nil导致异常 if (CGRectIsEmpty(view.frame)) { return nil; } UIGraphicsBeginImageContextWithOptions(view.frame.size, YES, 0.0); if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; } else{ // 占用内存高 引起异常 [view.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
当视图快速切换时的崩溃
这个崩溃是使用了while循环连续截屏100次webview发现的,崩溃为EXE_BAD_ACCESS
原因是afterScreenUpdates设置为了YES.
为什么会崩溃呢? 因为设置为YES后,这些方法会等在view update结束在执行,如果在update结束前view被release了,会出现找不到view的问题.所以需要设置为NO.
12、XCODE调试时不显示变量值/指针地址的解决方案
1.Scheme中run里面确保设成debug
2.build settings-搜索optim,确保是-O0
3.build settings-搜索-O2,改成-g。这项最坑爹,好像是默认的设置成-O2的
13、比较两个图片是否相同
1.如果2张图片都被加载都resource中,而且图片名称已知,使用imageNamed:创建2个UIImage对象就好,然后用isequal去比较。
2.两张图片存储在ios沙盒的某个位置,未被加载到resource中,比较两个UIImage的data,看看是否相同。
NSString* file = [dic stringByAppendingPathComponent:path]; UIImage *image = [UIImage imageWithContentsOfFile:file]; NSData *data1 = UIImagePNGRepresentation(image1); NSData *data = UIImagePNGRepresentation(image); if ([data isEqual:data1]) { NSLog(@"is equae"); }
14、UITableView间隔、颜色
要想改变其seperator的高度,是做不到的
首先,我们将其sperator设置为none。
其次,我们在构建tableview的时候,使用多secton,每个section中仅有一个row的方式构建。
第三,设置每个section的headerView的高度为要求的高度。
第四,重新定制每一个section的headerView,设置section的背景颜色为指定的颜色。
代码如下:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, height)]; //height为设计师制定的高度。 view.backgroundColor = [UIColor redColor]; return view; }
15、实时检测UITextField的变化
使用UISearchBar,UISearchBar的内容动态改变的时候,我们是可以通过代理来获知这个改变的。
在使用UITextField的时候,没有合适的代理函数,使用注册通知。
// 1,在initWithNibName中注册对应的通知: - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:_passwordTextField]; } return self; } // 2,实现textFieldChanged函数 - (void)textFieldChanged:(id)sender { NSLog(@"current ContentOffset is %@",NSStringFromCGPoint(_contentView.contentOffset)); } // 3,记得在dealloc中删除掉通知。 - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; }
16、UITextField加阴影
UITextView输入的时候,文字下面有阴影,系统默认只有UILabel有几个简单的接口可以设阴影,
至于UITextView的阴影就基本上没人用了,给UITextView的文字加阴影的办法,即通过layer层来设置。
上代码
请记得加入 QuartzCore.framework。
View Code
17、判断程序第一次启动
View Code
18、查看UUID
1.查看 xx.app 文件的 UUID,terminal 中输入命令 :
·dwarfdump --uuid xx.app/xx (xx代表你的项目名)
2.查看 xx.app.dSYM 文件的 UUID ,在 terminal 中输入命令:
·dwarfdump --uuid xx.app.dSYM
3.crash 文件内第一行 Incident Identifier 就是该 crash 文件的 UUID。
19、禁用手势
<UIGestureRecognizerDelegate> self.navigationController.interactivePopGestureRecognizer.delegate = self; - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ return NO; }
20、NSString对UTF-8编码解码
// iOS中对字符串进行UTF-8编码:输出str字符串的UTF-8格式 [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // 解码:把str字符串以UTF-8规则进行解码 [str stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
21、手势与tableview事件冲突处理
// 在view上添加tag手势的时候,并且设置tag事件的代理 //然后根据具体的业务场景去写逻辑就可以了,比如 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { //Tip:我们可以通过打印touch.view来看看具体点击的view是具体是什么名称,像点击UITableViewCell时响应的View则是UITableViewCellContentView. if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) { //返回为NO则屏蔽手势事件 return NO; } return YES; }
22、ScrollView header悬停
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scrollView.contentOffset.y >= 50) { self.header.frame = CGRectMake(0, 0, 375, 35); [self.view addSubview:self.header]; } else { self.header.frame = CGRectMake(0, 50, 375, 35); [self.scrollView addSubview:self.header]; } }
23、从设备支持的字体中随机选择一个
// 从设备支持的字体中随机选择一个 NSString *fontName = @""; NSUInteger count1 = arc4random() % ([UIFont familyNames].count); NSString *familyName = [UIFont familyNames][count1]; NSUInteger count2 = [UIFont fontNamesForFamilyName:familyName].count; fontName = [UIFont fontNamesForFamilyName:familyName][arc4random() % count2];
24、UIFont 转 CGFontRef
// 创建 UIFont 字体 UIFont *font = [UIFont systemFontOfSize:15]; // 转换成 CGFontRef CFStringRef fontName = (__bridge CFStringRef)font.fontName; CGFontRef fontRef = CGFontCreateWithFontName(fontName);
25、字符串转日期失败 NSDataFormatter 格式设置:
//You're using the wrong formatter: NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy"]; NSDate *startDatePlain=[formatter dateFromString:start]; NSDate *endDatePlain=[formatter dateFromString:end]; //You need to use your detailformatter: NSDateFormatter *detailformatter = [[NSDateFormatter alloc] init]; [detailformatter setDateFormat:@"MM/dd/yyyy"]; NSDate *startDatePlain=[detailformatter dateFromString:start]; NSDate *endDatePlain=[detailformatter dateFromString:end]; //You've got the correct format set on detailformatter!