ios开发过程中遇到的细节总结

自己到现在毕业一年,总结了自己在前段时间开发当中遇到的的一些细节问题,水平有限,希望有可以帮助大家的

1,在OC中使用 “%s,__func__”打印出类名和方法例如:

NSlog(@“%s”,__func__);  

打印出 -[Person dealloc]

2,RunLoopa内部实现原理:

内部由do-while循环实现

作用:1,保证程序的持续运行 2,处理各种APP事件(滑动,定时器,selector)3,节省cpu资源,提高性能

Runloop与线程   

    1,每条线程都有一个唯一的与之对应的RunLoop对象      2,主线程的Runloop随着程序已自动创建好,但是子线程的Runloop需要手动创建。  3,获得主线程的Runloop方法是[NSRunloop mainRunloop];    4,创建子线程的Runloop方法时[NSRunLoop currentRunloop];

Runloop相关类:

1,CFRunLoopModeRef:  代表了RunLoop的运行模式,一个RunLoop可以包含若干个Mode,每个Mode包含若干个Source/Timer/Observer,每个RunLoop启东时,只能指定其中的一个Mode,这个Mode被称作currentMode。

主要的几个Mode:KCFRunLoopDefaultMode:APP的默认Mode,通常主线程是在该Mode下运行的UITrackingRunLoopMode:界面追踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时,不受其他Mode影响KCFRunLoopCommonModes:这是一个占位用的Mode,不是真正的Mode,2,CFRunLoopSourceRef 3. CFRunLoopTimerRef 4, CFRunLoopObserverRef

3,定时器(NSTimer)定时器的创建:  

  self.timer = [NSTimer scheduledTimerWithTimeInterval:time target:self selector:@selector(move) userInfo:nil repeats:YES];

定时器的销毁: 

[self.timer invalidate];    self.timer = nil; (必须将销毁的对象置为nil,否则会运行程序会报错)

4,贝赛尔曲线的简单设置声明:

 UIBezierPath *bezierPath = [UIBezierPath bezierPath];

颜色的填充:[[UIColor cyanColor] set];

-(void)set:设置颜色,在当前绘制上下文中设置填充和线段颜色

-(void)setFill:设置填充

-(void)setStroke:设置线段

5,判断app是否第一次启动或者更新后的第一次启动

1 #define LAST_RUN_VERSION_KEY @"last_run_version_of_application" 

 - (BOOL) isFirstLoad{ 

 NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary]objectForKey:@"CFBundleShortVersionString"];    

 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

NSString *lastRunVersion = [defaults objectForKey:LAST_RUN_VERSION_KEY];  

 if (!lastRunVersion) {

  [defaults setObject:currentVersion forKey:LAST_RUN_VERSION_KEY];  

return YES;  

}  

else if (![lastRunVersion isEqualToString:currentVersion]) {  

[defaults setObject:currentVersion forKey:LAST_RUN_VERSION_KEY]; 

return YES;  }  

return NO;  

}  

6,设置按钮点击一瞬间变色或变背景图片,常态下是另一种颜色或背景图片,只需设置按钮平时状态和高亮状态下的颜色和图片即可。

7。KVC与KVO的用法总结 

 1,简单的KVC(一个对象,在.h文件中声明一个属性名,)

  最基本的操作属性的两个方法: 

 1, setValue:属性值forKey:属性名  为指定属性设置值    

 2,valueForKey:属性名  获取指定属性的值例子:

  //实例化一个对象 

 testView *tt = [[testView alloc]init];  

 //@“name”就是testViews声明的一个属性名  设定 

   [tt setValue:@"xiaobai " forKey:@“name"]; 

 //取值  

  NSString *nameStr = [tt valueForKey:@"name"];  

  NSLog(@"-------------------dsasdsad%@",nameStr); 

注意事项:为避免setValue 和  valueForKey在执行方法过程中找不到对应的属性名称,重写下面两个方法

//避免使用KVC设置的时候(即 setValue方法)程序崩溃,重写下面这个方法,抛出异常

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{ 

   NSLog(@"我没有这个属性%@",key);

}

//避免使用KVC读取的时候(即valueForKey方法)程序崩溃,重写下面这个方法,抛出异常

-(id)valueForUndefinedKey:(NSString *)key{ 

   NSLog(@"我没有这个属性%@",key);   

 return nil;

}

处理nil值

当调用KVC来设置对象的属性时,如果属性的类型是对象类型(NSString),尝试将属性设置为nil,是合法的,程序可以正常运行但是如果属性的类型是基本类型(如int,float,double),尝试将属性设置为nil,程序将会崩溃引发异常。当程序尝试为某个属性设置nil值时,如果该属性并不接受nil值,那么程序会执行该对象的setNilValueForKey:方法。同样可以重写这个方法避免异常

-(void)setNilValueForKey:(NSString *)key{    

int price; 

   if ([key isEqualToString:@"price"]) {   

     price = 0; 

   }else    {  

      [super setNilValueForKey:key];    

}}

KVC对集合的操作

例如可以获取数组中的一个最大值

NSArray *a = @[@4,@54,@2];

NSLog(@"max = %@",[a valueForKeyPath:@"@max.self"]);

KVO的操作

{self.person=[[Person alloc] init];  

  self.person.name=@"xiaowang";   

 //创建观察者监听person的name。只要name值改变就会收到消息  

  /*    1,谁是观察者  

  2,路径字符串,属性字符串写出来   

 3,收到通知后对哪些信息感兴趣,这里写对新值和旧值都感兴趣。   

 4.可以传递一些其他信息,不传递写nil即可。    */

    [self.person addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionNew |    NSKeyValueObservingOptionOld context:nil];    

    //当值改变的时候就会触发KVO   

 /*    通过点语法(setter)来修改属性会触发KVO,但是通过直接使用成员变量了修改属性,不会触发KVO    通过KVO来修改属性值会触发KVO    */  

  self.person.name=@"xiaohuang";  

 // [self.person change];      

  //[self.person setValue:@"xiaofen" forKey:@“name"];}

//监听属性name值一旦改变就会调用这个方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context

{

if ([keyPath isEqualToString:@"name"] && object == self.person) {

NSString *newname=change[@"new"];

NSString *oldname=change[@"old"];

NSLog(@"%@",oldname);

NSLog(@"%@",newname);

NSLog(@"%@",change);

}

}

8,打印oc中的CGPoint ,CGSize ,CGRect

NSLog(@"point: %@", NSStringFromCGPoint(point));

NSLog(@"size: %@", NSStringFromCGSize(size));

NSLog(@"rect: %@", NSStringFromCGRect(rect));

9,设置navigationbar的标题和返回按钮

self.view.backgroundColor = [UIColor colorWithRed:0xf2/255.0 green:0xf3/255.0 blue:0xf8/255.0 alpha:1];

self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:89/255.0 green:107/255.0 blue:159/255.0 alpha:1];

self.navigationItem.title = @"我的课程";

self.navigationController.navigationBar.tintColor = [UIColor whiteColor];

UIBarButtonItem *btn = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"back_btn"] style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];

self.navigationItem.leftBarButtonItem = btn;

10.创建tableview时候下面出现多余cell

添加如下代码:

self.tableView.tableFooterView=[[UIView alloc]init];//关键语句

11,关于日期的操作

a,获取n天后日期

-(NSString *)getNDay:(NSInteger)n{

NSDate*nowDate = [NSDate date];

NSDate* theDate;

if(n!=0){

NSTimeInterval  oneDay = 24*60*60*1;  //1天的长度

theDate = [nowDate initWithTimeIntervalSinceNow: oneDay*n ];//initWithTimeIntervalSinceNow是从现在往前后推的秒数

}else{

theDate = nowDate;

}

NSDateFormatter *date_formatter = [[NSDateFormatter alloc] init];

[date_formatter setDateFormat:@"MM月dd日"];

NSString *the_date_str = [date_formatter stringFromDate:theDate];

return the_date_str;

}

b,获取当天日期返回字符串

-(NSString *)getDate:(NSDate *)date

{

NSDateFormatter *format1=[[NSDateFormatter alloc]init];

[format1 setDateFormat:@"MM月dd日"];

NSString *str1=[format1 stringFromDate:date];

return str1;

}

c 传入日期返回相对应的周几

-(NSString *)getweek:(NSDate *)date{

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

//    NSDate *now;

NSDateComponents *comps = [[NSDateComponents alloc] init];

NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday |

NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;

//    now=[NSDate date];

comps = [calendar components:unitFlags fromDate:date];

NSArray * arrWeek=[NSArray arrayWithObjects:@"周日",@"周一",@"周二",@"周三",@"周四",@"周五",@"周六", nil];

NSString *str = [NSString stringWithFormat:@"%@",[arrWeek objectAtIndex:[comps weekday] - 1]];

return str;

}

d,获取当前日期八天以后的日期

-(NSMutableArray *)latelyEightTime{

NSMutableArray *eightArr = [[NSMutableArray alloc] init];

for (int i = 0; i < 7; i ++) {

//从现在开始的24小时

NSTimeInterval secondsPerDay = i * 24*60*60;

NSDate *curDate = [NSDate dateWithTimeIntervalSinceNow:secondsPerDay];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setDateFormat:@"M月d日"];

NSString *dateStr = [dateFormatter stringFromDate:curDate];//几月几号

NSDateFormatter *weekFormatter = [[NSDateFormatter alloc] init];

//真机调试会出现问题 添加如下代码:

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

[weekFormatter setLocale:locale];

[weekFormatter setDateFormat:@"EEEE"];//星期几 @"HH:mm 'on' EEEE MMMM d"];

NSString *weekStr = [weekFormatter stringFromDate:curDate];

//转换英文为中文

NSString *chinaStr = [self cTransformFromE:weekStr];

//组合时间

NSString *strTime = [NSString stringWithFormat:@"%@ %@",dateStr,chinaStr];

[eightArr addObject:strTime];

}

return eightArr;

}

-(NSString *)cTransformFromE:(NSString *)theWeek{

NSString *chinaStr;

if(theWeek){

if([theWeek isEqualToString:@"Monday"]){

chinaStr = @"周一";

}else if([theWeek isEqualToString:@"Tuesday"]){

chinaStr = @"周二";

}else if([theWeek isEqualToString:@"Wednesday"]){

chinaStr = @"周三";

}else if([theWeek isEqualToString:@"Thursday"]){

chinaStr = @"周四";

}else if([theWeek isEqualToString:@"Friday"]){

chinaStr = @"周五";

}else if([theWeek isEqualToString:@"Saturday"]){

chinaStr = @"周六";

}else if([theWeek isEqualToString:@"Sunday"]){

chinaStr = @"周七";

}

}

return chinaStr;

}

12,为防止背景图片变形,给button或label设置图片时候,先获取

UIimage *img = [uiimage imagenamed @“图片名称”];

设置背景色为图片的空间的宽高为img.size.width和img.size.height;

即可保证图片不会在控件中变形

13,设置点击手势时候,注意要把添加的组件的

组件.userInteractionEnabled = YES;打开

14,tableview默认选中第一行

[self.table_view selectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];

[self tableView:self.table_view didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];//实现点击第一行所调用的方法

15,对一个数判断如果是整数则取整数,如果有小数,取小数后两位

CGFloat money = [monLab floatValue] / 100;

float i=roundf(money);//对num取整

if (i==money) {

得到的数为:= [NSString stringWithFormat:@"%.0f",money];

}else{

得到的数为: = [NSString stringWithFormat:@"%.2f",money];

}

16.对不同的collectionview的item的布局

(除瀑布流之外)自动使得每行的item的宽度自动变化 ,调用collectionflowlayout的代理方法(遵守协议即可),对不同的collectionview判断每个item的字符串长度,要么一行显示一个,要不一行显示两个

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

{

CGSize itemSize = CGSizeMake(100, 50);

NSString *itemStr;

if (collectionView == self.collectionView) {

itemStr = [self.Querymodel.list[indexPath.item] termName];

}

else if (collectionView == self.MincollectionView)

{

itemStr = self.qiciTime[indexPath.item];

}

else if (collectionView == self.classTimeTableV)

{

itemStr = [self.Querymodel.list[indexPath.item] lessonName];

}

CGRect rect = [itemStr boundingRectWithSize:CGSizeMake(MAXFLOAT, 25) options:1 attributes:@{NSFontAttributeName :[UIFont systemFontOfSize:13]} context:nil];(判断每个字符串的长度方法)

if (rect.size.width > SCREEN_WIDTH/2 - 10) {

itemSize = CGSizeMake(SCREEN_WIDTH - 10 , 0.03748*SCREEN_HEIGHT);

}else

{

itemSize = CGSizeMake(SCREEN_WIDTH/2 - 20 , 0.03748*SCREEN_HEIGHT);

}

16 pickerview的使用方法和tableview的不同,必须是先定一列,然后确定每列的rows

- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

{

if (component == 0) {

return [[self.stuEleModel.elementList[0] theoptions][row] parentName];

}else

{

return [[[self.stuEleModel.elementList[0] theoptions][_proIndex] childrenList] [row]childrenName];

}

}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

{

if (component == 0) {

_proIndex = [pickerView selectedRowInComponent:0];

[_Stupick reloadComponent:1];

}

title1 = [[self.stuEleModel.elementList[0] theoptions][_proIndex] parentName];

NSInteger classIndex = [pickerView selectedRowInComponent:1];

title2 = [[[self.stuEleModel.elementList[0] theoptions][_proIndex] childrenList] [classIndex]childrenName];

_schoolClassB.text = [NSString stringWithFormat:@"%@-%@",title1,title2];

self.childrenId = [[self.stuEleModel.elementList[0] theoptions][_proIndex] parentId];

}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

{

if (component == 0) {

return [[self.stuEleModel.elementList[0] theoptions] count];

}

else{

return [[[self.stuEleModel.elementList[0] theoptions][_proIndex] childrenList] count];

}

}

17,label的属性设置(行间距,两边对齐)

NSString *testString = [NSString stringWithFormat:@"%@",self.model.venue.theDescription];

NSMutableParagraphStyle *paragraphSty = [[NSMutableParagraphStyle alloc]init];

paragraphSty.alignment = NSTextAlignmentJustified;

[paragraphSty setLineSpacing:4];

NSMutableAttributedString *setString = [[NSMutableAttributedString alloc]initWithString:testString];

[setString addAttribute:NSParagraphStyleAttributeName value:paragraphSty range:NSMakeRange(0, [testString length])];

[contentL setAttributedText:setString];

18,拨打电话不会有停顿

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@“tel://%@“,self.model.venue.phone]];(有时tel在个别手机不适用,可用telprompt)

NSString *version = [UIDevice currentDevice].systemVersion;

if ([version intValue] < 10.0 ) {

[[UIApplication sharedApplication] openURL:url];

}else{

[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {

}];

}

19,计算 webView 显示内容后求出内容的实际高度

链接: http://www.jianshu.com/p/f3aa4852e7de (用的是连接中第二种方法)

_webView = [[UIWebView alloc]initWithFrame:(CGRectMake(0, CGRectGetMaxY(line3.frame),SCREEN_WIDTH, 100))];

_webView.delegate= self;

_webView.layer.borderColor = [UIColor clearColor].CGColor;

_webView.layer.borderWidth = 1;

NSString *str = [NSString

stringWithFormat:@“%@",self.model.venue.theDescription];

[_webView loadHTMLString:str baseURL:nil];

-(void)webViewDidFinishLoad:(UIWebView *)webView

{

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

CGRect frame = webView.frame;

frame.size.width = SCREEN_WIDTH;

frame.size.height = 1;

webView.scrollView.scrollEnabled = NO;

webView.frame = frame;

frame.size.height = webView.scrollView.contentSize.height;

//        NSLog(@"frame = %@", [NSValue valueWithCGRect:frame]);

webView.frame = frame;

self.scrollView.contentSize = CGSizeMake(0, _lineHeight + frame.size.height);

});

}

20,一句话移除界面所有控件

[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

21,判断手机号码是否正确

+ (NSString *)valiMobile:(NSString *)mobile{

if (mobile.length < 11)

{

return @"手机号长度只能是11位";

}else{

/**

* 移动号段正则表达式

*/

NSString *CM_NUM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";

/**

* 联通号段正则表达式

*/

NSString *CU_NUM = @"^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";

/**

* 电信号段正则表达式

*/

NSString *CT_NUM = @"^((133)|(153)|(177)|(18[0,1,9]))\\d{8}$";

NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM_NUM];

BOOL isMatch1 = [pred1 evaluateWithObject:mobile];

NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU_NUM];

BOOL isMatch2 = [pred2 evaluateWithObject:mobile];

NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT_NUM];

BOOL isMatch3 = [pred3 evaluateWithObject:mobile];

if (isMatch1 || isMatch2 || isMatch3) {

return nil;

}else{

return @"请输入正确的电话号码";

}

}

return nil;

}

22,判断身份证号码

链接:http://www.cnblogs.com/yswdarren/p/3559423.html

①根据百度百科中身份证号码的标准实现该方法

②该方法只能判断18位身份证,且不能判断身份证号码和姓名是否对应(要看姓名和号码是否对应,应该有大量的数据库做对比才能实现)

③直接copy这段代码,就能通过调用这个方法判断身份证号码是否符合标准,非常easy

/**

*  验证身份证号码是否正确的方法

*

*  @param IDNumber 传进身份证号码字符串

*

*  @return 返回YES或NO表示该身份证号码是否符合国家标准

*/

- (BOOL)isCorrect:(NSString *)IDNumber

{

NSMutableArray *IDArray = [NSMutableArray array];

// 遍历身份证字符串,存入数组中

for (int i = 0; i < 18; i++) {

NSRange range = NSMakeRange(i, 1);

NSString *subString = [IDNumber substringWithRange:range];

[IDArray addObject:subString];

}

// 系数数组

NSArray *coefficientArray = [NSArray arrayWithObjects:@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2", nil];

// 余数数组

NSArray *remainderArray = [NSArray arrayWithObjects:@"1", @"0", @"X", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2", nil];

// 每一位身份证号码和对应系数相乘之后相加所得的和

int sum = 0;

for (int i = 0; i < 17; i++) {

int coefficient = [coefficientArray[i] intValue];

int ID = [IDArray[i] intValue];

sum += coefficient * ID;

}

// 这个和除以11的余数对应的数

NSString *str = remainderArray[(sum % 11)];

// 身份证号码最后一位

NSString *string = [IDNumber substringFromIndex:17];

// 如果这个数字和身份证最后一位相同,则符合国家标准,返回YES

if ([str isEqualToString:string]) {

return YES;

} else {

return NO;

}

}

23,将一个UIView显示在最前面只需要调用其父视图的 bringSubviewToFront()方法。

将一个UIView层推送到背后只需要调用其父视图的 sendSubviewToBack()方法。

24,当我们使用自动布局的时候为了不让Contraint和view本身的autoresize属性发生冲突,我们首先需要把控件的属性设置为 setTranslatesAutoresizingMaskIntoConstraints:NO

NSLayoutConstraint-代码实现自动布局

例子:

[NSLayoutConstraint constraintWithItem:view1

attribute:NSLayoutAttributeLeft

relatedBy:NSLayoutRelationEqual

toItem:view2

attribute:NSLayoutAttributeRight

multiplier:1

constant:10]

翻译过来就是:view1的左侧,在,view2的右侧,再多10个点,的地方。

25,xcode8.1以后调用相册需要在info.plist中添加字段Privacy - Privacy - Photo Library Usage Description 和 Privacy - Camera Usage Description

26,条形码和二维码的生成

a,条形码:

- (void)viewDidLoad {

//原生条形码

_barCodeImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 300, 128)];

_barCodeImageView.center=CGPointMake(ScreenWidth/2.0, 100+64);

[self.view addSubview:_barCodeImageView];

_barCodeImageView.image=[self generateBarCode:@"1234948958096" width:self.barCodeImageView.frame.size.width height:self.barCodeImageView.frame.size.height];

}

-(UIImage*)generateBarCode:(NSString*)barCodeStr width:(CGFloat)width height:(CGFloat)height

{

// 生成二维码图片

CIImage *barcodeImage;

NSData *data = [barCodeStr dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:false];

CIFilter *filter = [CIFilter filterWithName:@"CICode128BarcodeGenerator"];

[filter setValue:data forKey:@"inputMessage"];

barcodeImage = [filter outputImage];

// 消除模糊

CGFloat scaleX = width / barcodeImage.extent.size.width; // extent 返回图片的frame

CGFloat scaleY = height / barcodeImage.extent.size.height;

CIImage *transformedImage = [barcodeImage imageByApplyingTransform:CGAffineTransformScale(CGAffineTransformIdentity, scaleX, scaleY)];

return [UIImage imageWithCIImage:transformedImage];

}

b,二维码:

二维码生成步骤:

1.导入CoreImage框架

2.通过滤镜CIFilter生成二维码

示例代码:

1.创建过滤器

CIFilter*filter = [CIFilterfilterWithName:@"CIQRCodeGenerator"];

2.恢复默认

[filtersetDefaults];

3.给过滤器添加数据(正则表达式/账号和密码)

NSString*dataString =@"http://www.520it.com";

NSData*data = [dataStringdataUsingEncoding:NSUTF8StringEncoding];

[filtersetValue:dataforKeyPath:@"inputMessage"];

4.获取输出的二维码

CIImage*outputImage = [filteroutputImage];

5.显示二维码

self.imageView.image= [selfcreateNonInterpolatedUIImageFormCIImage:outputImagewithSize:200];

在第五步显示二维码的时候用了一个自己封装的方法(解决二维码图片不清晰)

具体方法如下:

*根据CIImage生成指定大小的UIImage

*

*  @param image CIImage

*  @param size图片宽度

- (UIImage*)createNonInterpolatedUIImageFormCIImage:(CIImage*)image withSize:(CGFloat) size

{

CGRectextent =CGRectIntegral(image.extent);

CGFloatscale =MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));

// 1.创建bitmap;

size_twidth =CGRectGetWidth(extent) * scale;

size_theight =CGRectGetHeight(extent) * scale;

CGColorSpaceRefcs =CGColorSpaceCreateDeviceGray();

CGContextRefbitmapRef =CGBitmapContextCreate(nil, width, height,8,0, cs, (CGBitmapInfo)kCGImageAlphaNone);

CIContext*context = [CIContextcontextWithOptions:nil];

CGImageRefbitmapImage = [contextcreateCGImage:imagefromRect:extent];

CGContextSetInterpolationQuality(bitmapRef,kCGInterpolationNone);

CGContextScaleCTM(bitmapRef, scale, scale);

CGContextDrawImage(bitmapRef, extent, bitmapImage);

// 2.保存bitmap到图片

CGImageRefscaledImage =CGBitmapContextCreateImage(bitmapRef);

CGContextRelease(bitmapRef);

CGImageRelease(bitmapImage);

return[UIImageimageWithCGImage:scaledImage];

}

27,通过向storyboard上面的页面进行传值

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

if ([segue.identifier isEqualToString:@"goto"])

{

NSIndexPath *indexPath=self.tableView.indexPathsForSelectedRows[0];

secondLastViewController *last=segue.destinationViewController;

VCOneItemOfItemsModel *one=_dataSource[indexPath.row];

last.url=one.url;

}

}

28,整个页面放弃编辑的方法

[self.view endEditing:YES];

29,在tableview中为实现viewForHeaderInSection方法,必须实现heightForHeaderInSection这个方法。

30,当tableview style设置为ground时,每个section的header会跟随tableview一起上下滑动;当style设置为plain时,每个section的header会悬浮在屏幕最上面,直到下一个section的header划过来,把当前的替换掉。但是当样式为group是,需要重写heightForHeaderInSection并且设置heightForFooterInSection:这个高度为0.1,这个协议方法,才会让组头视图显示出来,随着屏幕上下滑动。

31,可变数组使用addobject方法时:可以字节添加一个对象如@“axsa”,但是不能直接添加一个声明的变量,需要转换为NsNumber类型或NsString类型等其他类型进行存储。

32,自定义cell和自定义view需要实现的方法

a:自定义view在

-(instancetype)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self)

{ 写要添加的view

注意:不能像自定义cell中那里一样使用self.frame.size.height等属性,会报错。还是以屏幕的宽度和高度作参照。

}

}

方法中实现即可。

b:自定义tableviewcell在

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

{

if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {    仅需实例化要添加的组件 ,具体布局在下面方法中实现  }

}

-(void)layoutSubviews  //在该方法中实现cell里面组件的布局

{

[super layoutSubviews];//注意要先实现父视图的方法

}

33,事件响应的顺序:

//将事件传递给下一个响应者,让下一个响应者处理

[super touchesBegan:touches withEvent:event];

34,(tableview有时候头部会出现莫名的空白添加如下代码):

只要是滚动视图或者滚动视图的自子类,放到导航控制中,内容会自动向下偏移64,如果想取消这个偏移

self.automaticallyAdjustsScrollViewInsets=NO;

35,创建tabbar的时候添加子控制器

//创建控制器

NSString *viewControllerName = [NSString stringWithFormat:@"LZBViewController%d", i + 1];

Class cls = NSClassFromString(viewControllerName);

LZBBaseViewController *bvc = [[cls alloc] init];

bvc.tabBarItem = item;

//将控制器数组给分栏控制器管理

self.viewControllers = viewControllersArray;

36,CollectionView有关注意

a:创建collectionview的时候,需要提前创建layout布局,代码为:

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];

而不是UICollectionViewLayout  !!!!!

b:对于再给collectionview设置layout时候的两个如下属性:

layout.minimumLineSpacing

layout.minimumInteritemSpacing

系统默认情况下上下滚动时,此时minimumLineSpacing代表每行的行间距,minimumInteritemSpacing代表每列的列间距

如果修改滚动方向为水平滚动时,两个属性代表意义恰好相反:此时minimumLineSpacing代表每列的列间距,minimumInteritemSpacing代表每行的行间距

37,a:当把navigationbar隐藏的时候,滚动视图会留下空白的Top,(所有内容向下偏移20px),此时加:

self.automaticallyAdjustsScrollViewInsets = NO;//    自动滚动调整,默认为YES

b:在storyboard或xib上面设置navigationBar的颜色时,设置的颜色会和代码设置的颜色有色差,是因为ios7以上的默认navigationBar是半透明的,所以颜色会有差异,此时添加:

self.navigationController.navigationBar.translucent = NO;//    Bar的模糊效果,默认为YES

此时的整个视图的view会继续往下偏移,加代码:

self.edgesForExtendedLayout = UIRectEdgeNone;//    iOS7及以后的版本支持,self.view.frame.origin.y会下移64像素至navigationBar下方

38,label的高度自适应最简单的两句话

[lab.numberOfLines = 0];

[lab sizeToFit];

39,_weak和_unsafe_unretauned

1>都不是强指针(不是强引用),不能保住对象的命

2>_weak:所指向的对象销毁后,会自动变成nil指针(空指针),不再指向已经销毁的对象

3>_unsafe_unretauned:所指向的对象销毁后,指针仍指向已经销毁的对象.

40,使用cocoapods创建文件,创建podfile文件,想要创建那种可执行exec的黑色文件,创建完成在终端输入 chmod 700 文件名 ,想要恢复空白白色那种podfile文件,使用chmod 644 文件名。

41,用cocoapods创建项目流程(前提安装cocoapods)

1,打开终端,输入 cd + 空格 然后将项目根目录拖拽到终端上面 然后回车  输入touch Podfile 创建Podfile文件 返回项目文件夹打开Podfile文件 输入platform :ios保存退出。返回终端

例如:

platform :ios, '8.0'

use_frameworks!

target '项目名称' do

pod 'AFNetworking', '~>2.0'

pod 'MBProgressHUD','~>0.7'

pod 'SVPullToRefresh'

platform :ios,'6.0'

pod 'MJRefresh','~>2.4.7'

pod 'SDWebImage','~>3.7.3'

pod 'JSONModel','~>1.1.0'

pod 'NSData+MD5Digest', '~> 1.0.0'

pod 'Base64', '~> 1.0.1'

pod 'Masonry', '~> 0.6.3'

end,

2,回车,输入  pod+空格+install  然后回车,等待安装,安装完成点击项目

42,终端修改文件(vim常用命令)

链接:http://www.cnblogs.com/softwaretesting/archive/2011/07/12/2104435.html

1,打开单个文件

vim file

2,正常模式(按Esc或Ctrl+[进入) 左下角显示文件名或为空

插入模式(按i键进入) 左下角显示—INSERT--

3,:wq 保存并退出


未完待续。。。。。。

你可能感兴趣的:(ios开发过程中遇到的细节总结)