iOS小技术点备忘录

记录一些小技术点,方便使用时查找。

更改UITabBar && UINavigationBar背景颜色

1
2
[[UITabBar appearance] setBarTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];

更改UITabBar && UINavigationBar字体颜色

1
2
3
4
5
6
7
//改变按钮navigationBar tintColor颜色
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:102/255.0 green:102/255.0 blue:102/255.0 alpha:1.0];
//改变tabbar 正常颜色,选中色
NSDictionary *attributeNormal = @{NSForegroundColorAttributeName:[UIColor grayColor]};
[subVC.tabBarItem setTitleTextAttributes:attributeNormal forState:(UIControlStateNormal)];
NSDictionary *attributeSelected = @{NSForegroundColorAttributeName:[UIColor redColor]};
[subVC.tabBarItem setTitleTextAttributes:attributeSelected forState: (UIControlStateSelected)];

设置UIViewController的view的top在navigationBar下面 & bottom位置在Tabbar的上面

1
2
tabBarController.tabBar.translucent = NO;
uiviewController.navigationController.navigationBar.translucent = NO;

改变UISlider的进度条高度

需要继承UISlider并t重载trackRectForBounds方法

1
2
3
4
- (CGRect)trackRectForBounds:(CGRect)bounds
{
return CGRectMake(0, 0, CGRectGetWidth(self.frame), 5.0);
}

UIPageViewController 翻页效果

UIPageViewController的默认翻页效果类似于翻书的效果,如果想要平铺翻页和指定翻页方向呢?我们发现有navigationOrientation和transitionStyle两个属性,但是这两个属性是只读的,查看.h文件可知UIPageViewController提供了init方法

1
- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(nullable NSDictionary<NSString *, id> *)options NS_DESIGNATED_INITIALIZER;

所以需要改变默认的翻页效果和方向可以通过init方法实现;
1
2
3
4
NSDictionary *options = @{UIPageViewControllerOptionInterPageSpacingKey : @(0)};
_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:options];

push新页面时隐藏tabbar

1
2
3
UIViewController *viewController = [[UIViewController alloc] init];
[viewController setHidesBottomBarWhenPushed:YES];//一定要在push之前调用
[self.navigationController pushViewController:viewController animated:YES];

Xcode Build Settings Reference , pods配置时使用的key对照表

https://pewpewthespells.com/blog/buildsettings.html

正则匹配

1
2
3
4
5
6
7
8
9
10
- (BOOL)telePhoneMatchRules { //11位数字
BOOL match = NO;
NSString *telePhone = _telephoneField.text;
if (telePhone.length > 0){
NSString *regex = @"^\\d{11}$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
match = [pred evaluateWithObject:telePhone];
}
return NO;
}

更多正则参考:http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html

push到下级页面之前,无感知的移除某几个上级页面

1
2
3
4
5
6
7
8
9
10
11
[self.navigationController pushViewController:nextVC animated:YES];
NSMutableArray *controllers = [NSMutableArray array];
//移除前面的几个vc
for(UIViewController *viewController in self.navigationController.viewControllers){
if(![viewController isKindOfClass:[UIViewController1 class]] &&
![viewController isKindOfClass:[UIViewController2 class]] &&
![viewController isKindOfClass:[UIViewController3 class]]){
[controllers addObject:viewController];
}
}
[self.navigationController setViewControllers:[controllers copy]];

自定义UITableViewCell多选模式下选中和未选中的图片

在cell中实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)layoutSubviews {
[super layoutSubviews];
for (UIControl *control in self.subviews) {
if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]) {
for(UIView *view in control.subviews) {
//找到选中时的image
if ([view isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)view;
imageView.contentMode = UIViewContentModeScaleToFill;
if(self.selected) {
imageView.image = [UIImage imageNamed:@"ac_selectedImage"];
}else {
imageView.image = [UIImage imageNamed:@"ac_disSelectedImage"];
}
}
}
}
}
}

判断今天、明天、后天

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NSTimeInterval sencondDay = 24 * 60 * 60;
NSDate *today = [NSDate date];
NSDate *tomorrow = [today dateByAddingTimeInterval:sencondDay];
NSDate *postnatal = [today dateByAddingTimeInterval:sencondDay * 2];
// 10 first characters of description is the calendar date:
NSString *todayString = [[today description] substringToIndex:10];
NSString *tomorrowString = [[tomorrow description] substringToIndex:10];
NSString *postnatalString = [[postnatal description] substringToIndex:10];
NSString *dateString = [[date description] substringToIndex:10];
if ([todayString isEqualToString:dateString]) {
repeatDetail = @"今天 仅一次";
}
else if ([tomorrowString isEqualToString:dateString]) {
repeatDetail = @"明天 仅一次";
}
else if ([postnatalString isEqualToString:dateString]) {
repeatDetail = @"后天 仅一次";
}

隐藏导航条和显示导航条的页面间返回手势平滑切换

1
2
3
4
5
6
7
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//重点方法
[self.navigationController setNavigationBarHidden:YES animated:YES];
//[self.navigationController setNavigationBarHidden:NO animated:YES]; //从不显示的页面返回显示页面
}

或者是使用开源库:FDFullscreenPopGesture

改变UITableViewCell复选框默认图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)layoutSubviews {
[super layoutSubviews];
for (UIControl *control in self.subviews) {
if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellEditControl")]) {
for(UIView *view in control.subviews) {
//找到选中时的image
if ([view isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)view;
imageView.contentMode = UIViewContentModeScaleToFill;
if(self.selected) {
imageView.image = [UIImage imageNamed:@"ac_selectedImage"];
}else {
imageView.image = [UIImage imageNamed:@"ac_disSelectedImage"];
}
}
}
}
}
}

但是会偶现某些cell还是出现默认复选框的情况,应该是重用时没有触发layoutSubviews导致,所以并不是很好

设备信息,app信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];  
// app名称
NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
// app版本
NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
// app build版本
NSString *app_build = [infoDictionary objectForKey:@"CFBundleVersion"];

//手机序列号
NSString* identifierNumber = [[UIDevice currentDevice] uniqueIdentifier];
NSLog(@"手机序列号: %@",identifierNumber);
//手机别名: 用户定义的名称
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 );

NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
// 当前应用名称
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);

手机震动一下

1
2
#import <AudioToolbox/AudioToolbox.h>
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

顶部导航条电量信息变色

重写preferredStatusBarStyle方法,比如变成白色

1
2
3
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}

设置TextField属性之文字距左边框的距离

textfield有个属性leftview,设置一个只有宽度的leftView.然后需要将leftViewMode设置为UITextFieldViewModeAlways.因为默认textfield.leftView是不显示的.

iOS中调整view层级位置的两个属性

控件的层级关系和你加入到父视图的顺序有关,也就是先addsubview至父视图的,层级越低,会被后加入的遮盖。
可以通过以下函数改变子视图的层级
将一个UIView显示在调用者view最前面:

1
- (void)bringSubviewToFront:(UIView *)view;

将视图显示在下面:
1
- (void)sendSubviewToBack:(UIView *)view;

改变状态栏背景色导致返回手势过程(从有导航条->隐藏导航条)中,导航条突然消失问题

1
2
3
4
5
6
7
//重写 UINavigationController 得方法
- (UIViewController *)childViewControllerForStatusBarStyle{
  return self.visibleViewController;
}
- (UIViewController *)childViewControllerForStatusBarHidden{
  return self.visibleViewController;
}

打包突然出现errSecInternalComponent Command /usr/bin/codesign failed with exit code 1错误

Xcode bug,可能是过期证书过多,清理过期证书,或者重启mac!!!

UIPickerView 中间黑线消失的问题

问题描述:使用UIPickerView过程中发现在某种情况下pickview的两条默认的黑线消失了!!!
测试发现在viewDidLoad中add到view上的pickview的线又会显示!!!
查找问题:查找发现黑色线的设置是通过-[UIPickerView _setMagnifierLineColor:]方法设置的,不显示黑线是因为在-[UIPickerView _setMagnifierLineColor:]这个方法调用得时候pickview的subviews为nil,自然给线的view设置颜色无效。但是为什么在viewDidLoad中add到view上的pickview的线会显示呢?断点发现在这种情况下-[UIPickerView _setMagnifierLineColor:]会被调用两次,第一次调用时pickview的subviews依然为nil,第二次subviews中则包含了两根线的view。

猜想:苹果的bug,设置颜色的方法不应该在subviews还没准备好的时候去调用。
暂时的解决办法:在pickview被添加到父view的时候调用layoutSubviews方法,让其subviews先绘制出来;