1. 设置系统tabbar中TabBarItem选中的颜色
示例代码:
* [[UITabBarItem appearance] setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:10 weight:UIFontWeightMedium],NSForegroundColorAttributeName:[UIColor colorWithHexString:@"#333333"]} forState:UIControlStateSelected];
* [[UITabBarItem appearance] setTitleTextAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:10 weight:UIFontWeightRegular],NSForegroundColorAttributeName:[UIColor grayColor]} forState:UIControlStateNormal];
2.给设置圆角的的View设置阴影
情况描述
大家都知道给一个View设置圆角和简单,给一个View设置阴影也很简单,但是发现当一个View设置了圆角后,在给其设置阴影会发现一点都不简单了,没有效果。what is happen?
原来设置圆角的代码:masksToBounds = YES 把阴影给剪切掉了啊。怎么办呢?
考虑了很久,想到把设置阴影的View放到一个父视图上,然后在父视图上设置阴影,核心代码如下:
UIView *shadowView = [[UIView alloc]initWithFrame:self.layoutView.frame];
[self.view addSubview:shadowView];
shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
//偏移角度 (当为CGSizeMark(0,0) 则设置阴影的视图的周围都有一圈阴影)
shadowView.layer.shadowOffset = CGSizeMake(5, 5);
shadowView.layer.shadowOpacity = 0.5f;
shadowView.layer.shadowRadius = 9.0;//圆角宽度
shadowView.layer.cornerRadius = 9.0; //圆角半径
shadowView.clipsToBounds = NO;
[shadowView addSubview:self.layoutView];
3.在使用CocoaPod管理项目时,有时会更新podFile文件,这是一般要执行pod update
可能这是会出现把其他三方更新到最新的情况,而这时往往又使我们不愿看到的,这时可以使用如下命令防止这一情况:
pod update --verbose --no-repo-update
4. iOS开发,Xcode 出现Could not build module 'Foundation'类似的错误
1 引用问题
- 检查pch 是否导入头文件 , 导入是否可用
- 解决:在引用头文件开始加入#ifdef OBJC 结束时加入#endif,例如
ifndef PureStandard_PrefixHeader_pch
define PureStandard_PrefixHeader_pch
ifdef __OBJC__
import "A.h"
import "B.h"
#endif
2. 系统文件(Xcode文件)被修改
可能性:UIKit等库损坏或被修改(不能修改,一改就坏),也就是你查看Xcode编译器系统文件时不小心改了
- 可以恢复的就撤销的就撤销。
- 不能撤销的就只有花几十分钟重新安装Xcode了
5. iOS对象(字典或数组)转化为JSon字符串
使用系统自带的NSJSONSerialization可以满足常用的JSON转化 (可以抛弃所有三方了毕竟很久没更新了)
使用示例:
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setValue:@"hello" forKey:@"one"];
[dictionary setValue:@"world" forKey:@"two"];
NSArray *arry=[NSArray arrayWithObjects:@"001",@"002",@"003", nil];
[dictionary setValue:arry forKey:@"three"];
NSData *data=[NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil]; //此处可以传字典数组,或者数组字典
NSString *jsonStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"jsonStr==%@",jsonStr);
输出结果为:
str=={
"one" : "hello",
"two" : "world",
"three" : [
"001",
"002",
"003"
]
}
注意: 此处转换后的JSON字符串带有很多空格和换行符
要去掉的话,根据苹果API 解释可以这样操作:
NSData *data=[NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; //为0 就会得到我们想要的结果
6. 计算Label中文字的行数和每行中的文字
这中需求其实还是很容易遇到的,可能遇到有不同的解决方案,
这里找到一个比较简便的方案:
#import (包含头文件)
- (NSArray *)getLinesArrayOfStringInLabel:(UILabel *)label{
NSString *text = [label text];
UIFont *font = [label font];
CGRect rect = [label frame];
CTFontRef myFont = CTFontCreateWithName(( CFStringRef)([font fontName]), [font pointSize], NULL);
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:text];
[attStr addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)myFont range:NSMakeRange(0, attStr.length)];
CFRelease(myFont);
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString(( CFAttributedStringRef)attStr);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0,0,rect.size.width,100000));
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, NULL);
NSArray *lines = ( NSArray *)CTFrameGetLines(frame);
NSMutableArray *linesArray = [[NSMutableArray alloc]init];
for (id line in lines) {
CTLineRef lineRef = (__bridge CTLineRef )line;
CFRange lineRange = CTLineGetStringRange(lineRef);
NSRange range = NSMakeRange(lineRange.location, lineRange.length);
NSString *lineString = [text substringWithRange:range];
CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithFloat:0.0]));
CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attStr, lineRange, kCTKernAttributeName, (CFTypeRef)([NSNumber numberWithInt:0.0]));
//NSLog(@"''''''''''''''''''%@",lineString);
[linesArray addObject:lineString];
}
CGPathRelease(path);
CFRelease( frame );
CFRelease(frameSetter);
return (NSArray *)linesArray;
}
7. 全局取消视图响应 比如让键盘消失
当然这些控件一般都有自带的取消第一响应者的方法,但是系统也有通用的全局取消方法,最常用的方法如下:
[self.view endEditing:YES];
但是当有些响应者的视图没在当前视图上,这是用上面的方法就不可行了,我找了半天终于找到一个方法:
[[UIApplication sharedApplication].keyWindow endEditing:YES];
8. UITextField 限制字符长度
网上找了很多方法但是没有找找到完美的放啊,最厚终于找打了一个方法里面具体内容如下:
[self.truckWeight addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
- (void)textFieldDidChange:(UITextField *)textField{
NSInteger kMaxLength = 5;
NSString *toBeString = textField.text;
NSString *lang = [[UIApplication sharedApplication]textInputMode].primaryLanguage;
if ([lang isEqualToString:@"zh-Hans"]) { //中文输入
UITextRange *selectedRange = [textField markedTextRange];
//获取高亮部分
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if (!position) {// 没有高亮选择的字,则对已输入的文字进行字数统计和限制
if (toBeString.length > kMaxLength) {
textField.text = [toBeString substringToIndex:kMaxLength];
}
}
else{//有高亮选择的字符串,则暂不对文字进行统计和限制
}
}else{//中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
if (toBeString.length > kMaxLength) {
textField.text = [toBeString substringToIndex:kMaxLength];
}
}
}
9. UITextField 只能输入数字并且只有2位小数
这个和上面的限制可以同时使用 还是有很多这种奇葩需求的
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.truckWeight) {
NSScanner *scanner = [NSScanner scannerWithString:string];
NSCharacterSet *numbers;
NSRange pointRange = [textField.text rangeOfString:@"."];
if ( (pointRange.length > 0) && (pointRange.location < range.location || pointRange.location > range.location + range.length) )
{
numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
}
else
{
numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];
}
if ( [textField.text isEqualToString:@""] && [string isEqualToString:@"."] )
{
return NO;
}
short remain = 2; //默认保留2位小数
NSString *tempStr = [textField.text stringByAppendingString:string];
NSUInteger strlen = [tempStr length];
if(pointRange.length > 0 && pointRange.location > 0){ //判断输入框内是否含有“.”。
if([string isEqualToString:@"."]){ //当输入框内已经含有“.”时,如果再输入“.”则被视为无效。
return NO;
}
if(strlen > 0 && (strlen - pointRange.location) > remain+1){ //当输入框内已经含有“.”,当字符串长度减去小数点前面的字符串长度大于需要要保留的小数点位数,则视当次输入无效。
return NO;
}
}
NSRange zeroRange = [textField.text rangeOfString:@"0"];
if(zeroRange.length == 1 && zeroRange.location == 0){ //判断输入框第一个字符是否为“0”
if(![string isEqualToString:@"0"] && ![string isEqualToString:@"."] && [textField.text length] == 1){ //当输入框只有一个字符并且字符为“0”时,再输入不为“0”或者“.”的字符时,则将此输入替换输入框的这唯一字符。
textField.text = string;
return NO;
}else{
if(pointRange.length == 0 && pointRange.location > 0){ //当输入框第一个字符为“0”时,并且没有“.”字符时,如果当此输入的字符为“0”,则视当此输入无效。
if([string isEqualToString:@"0"]){
return NO;
}
}
}
}
NSString *buffer;
if ( ![scanner scanCharactersFromSet:numbers intoString:&buffer] && ([string length] != 0) )
{
return NO;
}
}
return YES;
}
10 AF请求失败打印后代服务器具体错误详情方法
在iOS端一般网络请求都是使用AF的,有时和后台调试的时候回遇到各种请求失败,一般的请求失败会在失败中返回具体失败原因,但是也会遇到特殊情况,比如失败原因就一句简单的话,这时候后台也没法具体打印调试信息的时候,可以使用下列方法来打印出具体的后台出错代码位置和基本信息
/*
//打印服务器错误代码,
NSData * data = error.userInfo[@"com.alamofire.serialization.response.error.data"];
NSString * str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"服务器的错误原因:%@",str);
*/
11.获取WebView 内容高度完美方法,网上肯定看到过很多类似的方法:可是很多不是很好,总有各种缺陷:下面找到一中完美解决这个问题的方案(使用KVC)
直接上代码:
self.webView.ScrollView.scrollEnabled = NO;
//注册KVO
[self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
//添加监听
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentSize"]) {
CGFloat contentHeight = self.webView.scrollView.contentSize.height;
// self.webView.height = contentHeight;
self.webViewHeightContraint.constant = contentHeight; // autoLayout
}
}
//移除监听
[webView.scrollView removeObserver:self forKeyPath:@"contentSize" context:nil];
12.获取UIWebView加载后的高度
网上有各种方法来获取webView 的内容高度,但是常常有一个问题就是WebView 过长的的时候,内容并没有显示完,这个时候通用的方法就不可行了。
下面提供一个不错的方法通过KVO 来实现获取WebView 的高度
直接上代码:
// 初始化的时候
[self.contentWebView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
//添加和移除KVO 观察者
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"contentSize"]) {
CGFloat contentHeight = self.contentWebView.scrollView.contentSize.height;
self.contentViewHight.constant = contentHeight;
}
}
- (void)dealloc{
[self.contentWebView.scrollView removeObserver:self forKeyPath:@"contentSize" context:nil];
}
13. 导航返回到指定页面
我们常常会有一些需求 需要点击返回按钮的时候返回到导航栏栈中的特定页面,这时候一般用的系统的方法如下:
[self.navigationController popToViewController: animated:YES]
这个确实可以满足需求,但是一般的返回除了点击左上返回外,还有右滑返回,这时候就会出现滑动到一半显示的还是上个页面视图,这就存在问题了,这时候就需要换一种方式实现这个需求了,那就是在push 到下个页面的时候不要用push方法,而要用setViewControllers: 方法,这样就能解决这个问题了
具体代码如下:
vc = ******
NSMutableArray *currentArr = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
if (currentArr.count >= 2) {
[currentArr replaceObjectAtIndex:currentArr.count - 1 withObject:vc];
}
[self.navigationController setViewControllers:currentArr animated:YES];
别担心这个动画效果和Push效果是一模一样的哦,真佩服乔布斯,
14 判断触摸点是否在某个视图内简单方法
啥都不用说,直接上代码
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CALayer *testViewLayer = self.testView.layer.presentationLayer;
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
if (CGRectContainsPoint(testViewLayer.frame, touchPoint)) {
NSLog(@"触摸点在视图内");
}