开发遇到的...

来源:互联网 发布:python 流量 预测 编辑:程序博客网 时间:2024/05/02 00:17

创建表格:create table if not exists t_contact (id integer primary key autoincrement,name text,phone text);


:

insert into t_contact (name,phone) values ('qiuxuewei','18518914551')


改:

update t_contact set name = qiuxuewei2


删:

delete from 表名


查:

select * from 表名 where 字段名 > 10;





//  ?  表示数据库里面的占位符   ? 指定的只能是对象,要是基本数据类型包装成对象

数据存储的四个方式:

1. plist :只能存储NSArray,  NSDictionary,只能存储数组和字典,不能有自定义对象

2. 偏好设置: 也不能存储自定义对象

3.归档: 可以存储自定义对象,不过要一次性做读取和存储的操作

4. SQLite数据库:

1> 操作数据比较快

2>可以局部的额度去

3>比较小型,占用的内存资源比较少



操作数据库的步骤:

0>打开数据库

1>创建数据表,表明,通常以t_xxx

2>创建表的字段,看下表需要存储什么数据就添加什么字段(字段必须有一个主键,记录的唯一标示符)

3>记录数据



数据库文件不能保存在document文件夹下,会被拒!!!





数据定义语句(DDLData Definition Language

包括createdrop等操作

在数据库中创建新表或删除表(create tabledrop table


数据操作语句(DMLData Manipulation Language

包括insertupdatedelete等操作

上面的3种操作分别用于添加、修改、删除表中的数据


数据查询语句(DQLData Query Language

可以用于查询获得表中的数据

关键字selectDQL(也是所有SQL)用得最多的操作

其他DQL常用的关键字有whereorder bygroup byhaving




真机调试的步骤:

1. 装一个开发者证书,让电脑具有真机调试的功能

2. 在后台生成一个bundle ID

3. 在后台添加手机的UUID

4. 生成一个描述文件



打包调试步骤:

1. 装一个证书,打包的证书

2. 生成一个bundle ID

3. 添加手机的UUID

4. 生成一个描述文件

 *在Xcode6里打包应用程序的时候输入账号就会自动添加描述文件

5. 利用Xcode打包应用程序







#pragma mark - 选择照片

- (IBAction)chooseImage {

    

    //判断照片源是否可用

    if (![UIImagePickerControllerisSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;

    

    //创建照片选择控制器

    UIImagePickerController *ipc = [[UIImagePickerControlleralloc] init];

    

    //设置照片源

    ipc.sourceType =UIImagePickerControllerSourceTypeSavedPhotosAlbum;

    

    //设置代理

    ipc.delegate =self;

    

    //弹出控制器

    [selfpresentViewController:ipc animated:YEScompletion:nil];

    

}





开启程序将图标右上角的数字清除需要在控制器的viewDidLoad中加一句:

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]







代理和block区别:


代理:打电话让别人去做事情

block:让小弟去做事情








        //这个是把数组加进去

//        [self.statuses addObject:statusArr];

        //这个是把数组的元素加进去

        [self.statusesaddObjectsFromArray:statusArr];












请求数据常规开发步骤:

1、查看接口文档

2、依据参数列表,设置参数模型

3、依据结果,设置结果模型

4、直接拿到对应的工具类处理


软件开发步骤:  搭建界面 ————> 展示数据 ————> 处理对应的业务逻辑


1、向服务器发送数据  —》一般公司会提供一个接口文档,参照接口文档跟服务器打交道,接口文档(1、请求的url, 2、发送什么样的请求(GET/POST)3、返回数据的格式)


2、服务器相应数据  —》 解析数据,参照接口文档设计模型 —》返回数据转化为模型


3、把数据展示到界面,刷新表格!!!!!












归档:(模型归档必须要遵守一个协议NSCoding!!!!!!!!!!!!!)

数据存储一般会搞一个业务类,专门处理数据的存储

//以后不想归档用数据库可以直接修改业务类

//归档

#define XWAccountFilePath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.data"]


//归档

[NSKeyedArchiverarchiveRootObject:account toFile:XWAccountFilePath];        

//解档

[NSKeyedUnarchiverunarchiveObjectWithFile:XWAccountFilePath];


——————————————

//归档(告诉系统哪些属性需要归档!)

- (void)encodeWithCoder:(NSCoder *)aCoder{

    [aCoderencodeObject:self.access_tokenforKey:XWAccess_token];

    [aCoderencodeObject:self.expires_inforKey:XWExpires_in];

    [aCoderencodeObject:self.uidforKey:XWUil];

}


//解档(告诉系统哪些属性解档)

- (id)initWithCoder:(NSCoder *)aDecoder{

   if ([super init]) {

        //解档完之后保存到属性中,不要白解了!!

       self.access_token = [aDecoderdecodeObjectForKey:XWAccess_token];

       self.expires_in = [aDecoderdecodeObjectForKey:XWExpires_in];

       self.uid = [aDecoderdecodeObjectForKey:XWUil];

    }

    return self;

}





//KVC的底层实现原理:

/**

 遍历字典里的所有key:

 dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

 <#code#>

 }

 

 一个个获取key,回去模型里查找有没有setKey方法:比如:

 -(void)setUid:(NSString *)uid{}

 

 如果有直接调用这个方法赋值比如:setUid:obj

 

 如果没有查找有没有带下划线的_key  _uid,直接拿到属性,如果有直接赋值

 

 如果找不到对应的key,就会报错

*/








偏好设置的好处:

1、不需要关心文件名

2、快速进行键值对存储







UICollectionView必须初始化布局才能显示


/**

 使用UICollectionViewController的步骤:

1、初始化UICollectionViewFlowLayout布局参数:

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

     

     //设置cell的尺寸

     layout.itemSize = [UIScreen mainScreen].bounds.size;

     

     //清空行距

     layout.minimumLineSpacing = 0;

     

     //设置水平滚动的方向

     layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

     

     return [super initWithCollectionViewLayout:layout];


2、使用collection必须要注册cell[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ID];

3、自定义cell

*/





注意!!!!!

UITableView  和  UICollectionView  添加子控件要添加在self.contentView上面!!!!








//    //创建搜索框

//    UISearchBar *searchBar = [[UISearchBar alloc] init];

//    searchBar.placeholder = @"搜索占位符";

   UITextField *searchBar = [[UITextFieldalloc] initWithFrame:CGRectMake(0,0, [UIScreenmainScreen].bounds.size.width,30)];

    searchBar.placeholder =@"搜索占位符";

    searchBar.background = [UIImageimageNamed:@"searchbar_textfield_background"];

    UIImageView *imageView = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"searchbar_textfield_search_icon"]];

//    imageView.frame = CGRectMake(0, 0, 15, 15);

    searchBar.leftView = imageView;

    //想要显示UITextField左边的leftView一定要设置这个属性

    searchBar.leftViewMode =UITextFieldViewModeAlways;

    self.navigationItem.titleView = searchBar;








//什么时候调用:从程序一启动的时候就会把所有的类加载进内存

//作用:加载类的时候调用

+(void)load{

   NSLog(@"%s",__func__);

}


//什么时候调用:当第一次使用这个类或者这个类的子类的时候调用

//作用:初始化类的时候

+(void)initialize{

   NSLog(@"%s",__func__);

}



//appearance  只要遵守UIAppearance协议,就能获取外观

 //获取所有的tabarItem外观标示,包括系统自带类

UITabBarItem *item = [UITabBarItemappearance];

 //获取所有的tabarItem外观标示,只当前类

UITabBarItem *itemW = [UITabBarItem appearanceWhenContainedIn:self,nil];



//创建搜索框

   UISearchBar *searchBar = [[UISearchBaralloc] init];

    searchBar.placeholder =@"搜索占位符";




 //默认会根据按钮的背景图片、图片、文字计算出最合适的尺寸

        [_plusButtnsizeToFit];




//修改系统tabbar上按钮的位置,需要自定tabbar才能实现

   XWTabBar *tabBar = [[XWTabBaralloc] initWithFrame:self.tabBar.frame];


    //利用KVC可以修改readONLY属性

    [selfsetValue:tabBar forKeyPath:@"tabBar"];







工厂方法不能用id而要用instance声明返回值类型的原因:

1id可以调用任何类的get、set方法,不会帮我们检查语法错误,只能在运行时崩溃

2instance可以自动识别调用的类是父类还是子类并且自动识别其方法变量








判断当前设备是iOS8 还是iOS7

 if ([[UIDevicecurrentDevice].systemVersiondoubleValue] >= 8.0) {

       NSLog(@"iOS8");

        

    }else{

       NSLog(@"iOS7");

    }










 // UIScrollView 垂直方向上永远可以拖拽(有弹簧效果)

    textView.alwaysBounceVertical =YES;










// 通知

        // UITextView的文字发生改变时,UITextView自己会发出一个UITextViewTextDidChangeNotification通知

        [HWNotificationCenteraddObserver:selfselector:@selector(textDidChange)name:UITextViewTextDidChangeNotificationobject:self];





// 重绘(重新调用drawRect),先把drowRect的内容擦掉

 

    [selfsetNeedsDisplay];




/**

 UITextField:

     1.文字永远是一行,不能显示多行文字

     2.placehoder属性设置占位文字

     3.继承自UIControl

     4.监听行为

     1> 设置代理

     2> addTarget:action:forControlEvents:

     3> 通知:UITextFieldTextDidChangeNotification

 

 UITextView:

     1.能显示任意行文字

     2.不能设置占位文字

     3.继承自UIScollView

     4.监听行为

     1> 设置代理

     2> 通知:UITextViewTextDidChangeNotification

 */















 // 内容模式

        self.contentMode =UIViewContentModeScaleAspectFill;

        // 超出边框的内容都剪掉

       self.clipsToBounds =YES;


/**

         UIViewContentModeScaleToFill : 图片拉伸至填充整个UIImageView(图片可能会变形)

         

         UIViewContentModeScaleAspectFit : 图片拉伸至完全显示在UIImageView里面为止(图片不会变形)

         

         UIViewContentModeScaleAspectFill : 

         图片拉伸至 图片的宽度等于UIImageView的宽度 或者 图片的高度等于UIImageView的高度为止

         

         UIViewContentModeRedraw : 调用了setNeedsDisplay方法时,就会将图片重新渲染

         

         UIViewContentModeCenter : 居中显示

         UIViewContentModeTop,

         UIViewContentModeBottom,

         UIViewContentModeLeft,

         UIViewContentModeRight,

         UIViewContentModeTopLeft,

         UIViewContentModeTopRight,

         UIViewContentModeBottomLeft,

         UIViewContentModeBottomRight,

         

         经验规律:

         1.凡是带有Scale单词的,图片都会拉伸

         2.凡是带有Aspect单词的,图片都会保持原来的宽高比,图片不会变形

         */

        








计算行数公式:

行数 = (  count  + max - 1  ) / max






@implementation NSDate (Extension)


/**

 *  判断某个时间是否为今年

 */

- (BOOL)isThisYear

{

   NSCalendar *calendar = [NSCalendarcurrentCalendar];

    //获得某个时间的年月日时分秒

    NSDateComponents *dateCmps = [calendarcomponents:NSCalendarUnitYearfromDate:self];

    NSDateComponents *nowCmps = [calendarcomponents:NSCalendarUnitYearfromDate:[NSDatedate]];

   return dateCmps.year == nowCmps.year;

}


/**

 *  判断某个时间是否为昨天

 */

- (BOOL)isYesterday

{

   NSDate *now = [NSDatedate];

    

    // date ==  2014-04-30 10:05:28 --> 2014-04-30 00:00:00

    // now == 2014-05-01 09:22:10 --> 2014-05-01 00:00:00

    NSDateFormatter *fmt = [[NSDateFormatteralloc] init];

    fmt.dateFormat =@"yyyy-MM-dd";

    

    // 2014-04-30

   NSString *dateStr = [fmt stringFromDate:self];

    // 2014-10-18

   NSString *nowStr = [fmt stringFromDate:now];

    

    // 2014-10-30 00:00:00

   NSDate *date = [fmt dateFromString:dateStr];

    // 2014-10-18 00:00:00

    now = [fmtdateFromString:nowStr];

    

   NSCalendar *calendar = [NSCalendarcurrentCalendar];

    

    NSCalendarUnit unit =NSCalendarUnitYear | NSCalendarUnitMonth |NSCalendarUnitDay;

   NSDateComponents *cmps = [calendar components:unit fromDate:date toDate:now options:0];

    

   return cmps.year ==0 && cmps.month ==0 && cmps.day ==1;

}


/**

 *  判断某个时间是否为今天

 */

- (BOOL)isToday

{

   NSDate *now = [NSDatedate];

    NSDateFormatter *fmt = [[NSDateFormatteralloc] init];

    fmt.dateFormat =@"yyyy-MM-dd";

    

   NSString *dateStr = [fmt stringFromDate:self];

   NSString *nowStr = [fmt stringFromDate:now];

    

   return [dateStr isEqualToString:nowStr];

}

@end




- (NSString *)created_at

{

    NSDateFormatter *fmt = [[NSDateFormatteralloc] init];

    //如果是真机调试,转换这种欧美时间,需要设置locale

    fmt.locale = [[NSLocalealloc] initWithLocaleIdentifier:@"en_US"];

    

    //设置日期格式(声明字符串里面每个数字和单词的含义)

    // E:星期几

    // M:月份

    // d:几号(这个月的第几天)

    // H:24小时制的小时

    // m:分钟

    // s:

    // y:

    fmt.dateFormat =@"EEE MMM dd HH:mm:ss Z yyyy";

//    _created_at = @"Tue Sep 30 17:06:25 +0800 2014";

    

    // 微博的创建日期

   NSDate *createDate = [fmt dateFromString:_created_at];

    // 当前时间

   NSDate *now = [NSDatedate];

    

    //日历对象(方便比较两个日期之间的差距)

   NSCalendar *calendar = [NSCalendarcurrentCalendar];

    // NSCalendarUnit枚举代表想获得哪些差值

    NSCalendarUnit unit =NSCalendarUnitYear | NSCalendarUnitMonth |NSCalendarUnitDay | NSCalendarUnitHour |NSCalendarUnitMinute | NSCalendarUnitSecond;

    //计算两个日期之间的差值

   NSDateComponents *cmps = [calendar components:unit fromDate:createDate toDate:now options:0];

    

   if ([createDate isThisYear]) {// 今年

       if ([createDate isYesterday]) {// 昨天

            fmt.dateFormat =@"昨天 HH:mm";

           return [fmt stringFromDate:createDate];

        }else if ([createDateisToday]) { // 今天

           if (cmps.hour >=1) {

               return [NSStringstringWithFormat:@"%d小时前", cmps.hour];

            }else if (cmps.minute >=1) {

               return [NSStringstringWithFormat:@"%d分钟前", cmps.minute];

            }else {

               return @"刚刚";

            }

        }else { // 今年的其他日子

            fmt.dateFormat =@"MM-dd HH:mm";

           return [fmt stringFromDate:createDate];

        }

    }else { // 非今年

        fmt.dateFormat =@"yyyy-MM-dd HH:mm";

       return [fmt stringFromDate:createDate];

    }

}









如果两个view是父子关系,一定会也要设置这两个view的控制器也设置为父子关系





⾃自定义cell的步骤(每个cell的⾼高度不⼀一样,每个cell⾥里⾯面显⽰示的内容也不⼀一样

1. 新建⼀一个继承⾃自UITableViewCell的⼦子类 

2. initWithStyle:⽅方法中进⾏行⼦子控件的初始化
1> 将有可能显⽰示的所有⼦子控件都添加到contentView
2> 顺便设置⼦子控件的⼀一些属性(⼀一次性的设置:字体、⽂文字颜⾊色、背景 

3. 提供2个模型
1> ⼀一个是数据模型(⽂文字数据+ 图⽚片数据)
2> ⼀一个是frame模型(数据模型+ 所有⼦子控件的frame + cell的⾼高度

4. cell应该提供⼀一个frame模型属性
1> frame模型传递给cell
2> cell
根据frame模型给⼦子控件设置frame,根据数据模型给⼦子控件设置数据
3> cell根据数据模型决定显⽰示和隐藏哪些⼦子控件 

5. tableView的代理⽅方法返回cell的⾼高度 












// 目的:想在系统计算和设置完按钮的尺寸后,再修改一下尺寸

/**

 *  重写setFrame:方法的目的:拦截设置按钮尺寸的过程

 *  如果想在系统设置完控件的尺寸后,再做修改,而且要保证修改成功,一般都是在setFrame:中设置

 */

- (void)setFrame:(CGRect)frame

{

    frame.size.width +=HWMargin;

    [supersetFrame:frame];

}








/**

 *  app进入后台时调用,使程序在进入后台也能进行操作

 */

- (void)applicationDidEnterBackground:(UIApplication *)application

{

   /**

     *  app的状态

     *  1.死亡状态:没有打开app

     *  2.前台运行状态

     *  3.后台暂停状态:停止一切动画、定时器、多媒体、联网操作,很难再作其他操作

     *  4.后台运行状态

     */

    //向操作系统申请后台运行的资格,能维持多久,是不确定的

    UIBackgroundTaskIdentifier task = [applicationbeginBackgroundTaskWithExpirationHandler:^{

        //当申请的后台运行时间已经结束(过期),就会调用这个block

        

        // 赶紧结束任务

        [applicationendBackgroundTask:task];

    }];

    

    // Info.plst中设置后台模式:Required background modes == App plays audio or streams audio/video using AirPlay

    // 搞一个0kbMP3文件,没有声音

    // 循环播放

    

    //以前的后台模式只有3

    // 保持网络连接

    // 多媒体应用

    // VOIP:网络电话

}










// @20 --> @"20"

        // NSNumber --> NSString

        // 设置提醒数字(微博的未读数)

       NSString *status = [responseObject[@"status"]description];








MJExtension框架使用::

#import "MJExtension.h"

#import "HWPerson.h"

#import "HWBook.h"


NO1:

字典转模型:[HWPersonobjectWithKeyValues:dict]

//如果模型里面有模型则首先声明下:objectClassInArray

HMPerson模型中包含HMBook模型,需要在HMPerson.m中声明一下:(注意声明之前要在.H文件中遵守<MJKeyvalue>

- (NSDictionary *)objectClassInArray

{

   return @{@"books" : [HWBookclass]};

}



main{


 NSDictionary *dict =@{

                              @"name" : @"张三",

                              @"books" : @[

                                      @{

                                          @"name" : @"葵花1",

                                          @"price" : @"10.6"

                                          },

                                      @{

                                          @"name" : @"葵花2",

                                          @"price" : @"10.9"

                                          },

                                      @{

                                          @"name" : @"葵花3",

                                          @"price" : @"17.6"

                                          },

                                      @{

                                          @"name" : @"葵花4",

                                          @"price" : @"14.4"

                                          }

                                      ]

                               

                              };

        

//直接将字典转化成模型

       HWPerson *person = [HWPersonobjectWithKeyValues:dict];

}



NO2:

//replacedKeyFromPropertyName:改变键值对的名

如果模型中有键值跟系统标示重复可以在.m中实现这个方法

- (NSDictionary *)replacedKeyFromPropertyName

{


//把id  ->  ID     text -> mytext

    return@{@"ID" : @"id", @"mytext" :@"text"};

}



NO3:

模型转化成字典:[statuskeyValues]


mian{


HWUser *user = [[HWUseralloc] init];

    user.profile_image_url =@"abc.png";

    user.idstr =@"4435435";

    user.name =@"旺财";

    

   HWStatus *status = [[HWStatusalloc] init];

    status.mytext =@"哈哈哈哈";

    status.user = user;

    

//status模型转化为字典

   NSDictionary *dict = [status keyValues];

}



NO4:

//[XWStatusobjectArrayWithKeyValuesArray:responseObject[@"statuses”]]将一个字典数组转化为模型数组,返回NSArray


// "微博字典"数组转为 "微博模型"数组

       self.statuses = [XWStatusobjectArrayWithKeyValuesArray:responseObject[@"statuses"]];









网络下载图片方法:

SDWebImage使用的好处:

1、异步下载,避免卡死主线程

2、已经做好图片缓存

3、已经解决循环利用



注意:容易造成内存警告

解决方法:在"AppDelegate.m”方法中定义这个方法!

//程序接收到内存警告的时候调用此方法

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{

    //1、停止所有下载

    [[SDWebImageManagersharedManager] cancelAll];

    

    //2、清除缓存

    [[SDWebImageManagersharedManager].imageCacheclearMemory];

}







导入SDWebImage框架,在类中#import  “UIImageView+WebCache.h”;


设置图片

[cell.imageViewsd_setImageWithURL:[NSURLURLWithString:imageUrl] placeholderImage:placehoder];


防止图片越来越多,需要手动管理图片缓存一般在XWAppDelegate.m方法中,导入

SDWebImageManager.h

再重写:

-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{

    SDWebImageManager *mgr = [SDWebImageManagersharedManager];

    //1、清除内存中所有图片

    [mgrcancelAll];

    

    //2、清除内存中所有图片

    [mgr.imageCacheclearMemory];   

}





 //设置按钮自适应

    [titleButtonsizeToFit];



// 如果图片的某个方向上不规则,比如有突起,那么这个方向就不能拉伸

// 什么情况下建议使用imageEdgeInsetstitleEdgeInsets

// 如果按钮内部的图片、文字固定,用这2个属性来设置间距,会比较简单

// 标题宽度

//    CGFloat titleW = titleButton.titleLabel.width * [UIScreen mainScreen].scale;

////    // 乘上scale系数,保证retina屏幕上的图片宽度是正确的

//    CGFloat imageW = titleButton.imageView.width * [UIScreen mainScreen].scale;

//    CGFloat left = titleW + imageW;

//    titleButton.imageEdgeInsets = UIEdgeInsetsMake(0, left, 0, 0);


    // 如果仅仅是调整按钮内部titleLabelimageView的位置,那么在layoutSubviews中单独设置位置即可





// 自定义对象的存储必须用NSKeyedArchiver,不再有什么writeToFile(字典和数组的写入)方法

//存

        [NSKeyedArchiverarchiveRootObject:account toFile:path];

//取

[NSKeyedUnarchiverunarchiveObjectWithFile:filePath];

!!!!!注意!!!!

模型存取沙盒必须在模型内遵守一个<NSCoding>协议!!!告诉控制器哪些属性写进沙盒


eg:

/**

 归档的时候调用!!

 *  当一个对象要归档的时候调用,归档之前调用。目的:在这个方法中说明哪些属性要存进沙盒

 *

 *  @param aCoder <#aCoder description#>

 */

-(void)encodeWithCoder:(NSCoder *)aCoder{

    [aCoderencodeObject:self.access_tokenforKey:@"access_token"];

    [aCoderencodeObject:self.uidforKey:@"uid"];

    [aCoderencodeObject:self.expires_inforKey:@"expires_in"];

}


/**

 *  当从沙盒中解档一个对象时(从沙盒中加载一个对象时),就会调用这个方法

 *  目的:在这个方法中说明沙盒中的属性该怎么解析(需要取出哪些属性)

 */

-(id)initWithCoder:(NSCoder *)aDecoder{

   if (self == [superinit]) {

       self.access_token = [aDecoderdecodeObjectForKey:@"access_token"];

       self.expires_in = [aDecoderdecodeObjectForKey:@"expires_in"];

       self.uid = [aDecoderdecodeObjectForKey:@"uid"];

    }

    return self;

}











 /*

     切换控制器的手段

     1.push:依赖于UINavigationController,控制器的切换是可逆的,比如A切换到BB又可以回到A

     2.modal:控制器的切换是可逆的,比如A切换到BB又可以回到A

     3.切换windowrootViewController


拿到主窗口方法

UIWindow *window = [UIApplicationsharedApplication].keyWindow;



//2、显示窗口

    [self.windowmakeKeyAndVisible];

     */


 //上一次的使用版本(存储在沙盒中的版本号)

       NSString *lastVersion = [[NSUserDefaultsstandardUserDefaults] objectForKey:key];

        // 当前软件的版本号(从Info.plist中获得)

       NSString *currentVersion = [NSBundlemainBundle].infoDictionary[key];







UIImageView默认不可用户交互。如果想让用户交互需要设置:

 imageView.userInteractionEnabled =YES;



// 很多重复代码 --->将重复代码抽取到一个方法中

    // 1.相同的代码放到一个方法中

    // 2.不同的东西变成参数

    // 3.在使用到这段代码的这个地方调用方法,传递参数


   


 

   /**

     //添加子控制器方法一:

     tabbarVc.viewControllers = @[vc1,vc2,vc3,vc4];

     */

    

    //添加自控器方法二:

//    [self addChildViewController:homeVc];

//    [self addChildViewController:messageVc];

//    [self addChildViewController:discoverVc];

//    [self addChildViewController:profileVc];




 /**

     //搞个随机色

     UIColor *color = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0];

     */



 // test1控制器被push的时候,test1所在的tabbarcontrollertabbar会自动隐藏

    // test1控制器被pop的时候,test1所在的tabbarcontrollertabbar会自动显示

    test1.hidesBottomBarWhenPushed =YES;


一、为什么要自定义UITabBarController

1.想把UITabBarController内部的子控制器细节屏蔽起来,不让外界了解

2.另外一个目的:每一段代码都应该放在最合适的地方


二、重复代码的抽取

1.相同的代码放到一个方法中

2.不同的东西变成参数

3.在需要用到这段代码的地方传递参数、调用方法


三、统一所有控制器导航栏左上角和右上角的内容

1.让所有push进来的控制器,它导航栏左上角和右上角的内容都一样

2."拦截"所有push进来的控制器

3.方案:自定义导航控制器,重写push方法,就可以得到传进来的控制器参数

// 90%"拦截"都是通过自定义类,重写自带的方法实现的


四、"duplicate symbol _OBJC_METACLASS_$_类名 in:"错误

1.90%都是因为#import.m文件

2.其他可能是因为项目中存在了2个一样的.m文件


五、创建UIBarButtonItem的代码为什么放在UIBarButtonItem分类中最合适?

/*

+ (UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage

{

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];

    // 设置图片

    [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];

    [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];

    // 设置尺寸

    btn.size = btn.currentBackgroundImage.size;

    return [[UIBarButtonItem alloc] initWithCustomView:btn];

}*/

1.项目中有多处地方用到这段代码

2.每一段代码都应该放在最合适的地方:这段代码明显在创建一个UIBarButtonItem,所以跟UIBarButtonItem相关

3.从命名习惯和规范的角度看:[UIBarButtonItem itemWith....]这种形式创建item比较规范





颜色在iOS中表示

//  每一个像素都有自己的颜色,每一种颜色都可以由RGB3色组成

    //  12bit颜色: #f00  #0f0 #00f #ff0

    //  24bit颜色: #ff0000 #ffff00  #000000  

//      32bit颜色:  多了透明度

    

    // #ff ff ff

    // R:255

    // G:255

    // B:255

    

    // RGBA



//    UIImage *image = [UIImage imageNamed:@"searchbar_textfield_search_icon"];

    // 通过initWithImage来创建初始化UIImageViewUIImageView的尺寸默认就等于image的尺寸

//    UIImageView *searchIcon = [[UIImageView alloc] initWithImage:image];

    

    //通过init来创建初始化绝大部分控件,控件都是没有尺寸

   UIImageView *searchIcon = [[UIImageViewalloc] init];







//    [UIApplication sharedApplication].keyWindow == self.view.window

    //建议使用[UIApplication sharedApplication].keyWindow获取窗口

    [[UIApplicationsharedApplication].keyWindowaddSubview:dropdownMenu];

//这样获得窗口是当前最上面的窗口

    UIWindow *window = [[UIApplicationsharedApplication].windowslastObject];

    [windowaddSubview:dropdownMenu];


imageView默认不能跟用户交互,上面添加的子控件也不能和用户交互,要想和用户交互需要设置子控件的userInteractionEnabled属性为YES







坐标系转换:

 // 计算self.yellowself.blue中的位置和尺寸

//    CGRect newRect = [self.yellow convertRect:self.yellow.bounds toView:self.blue];

    

    

    // 计算self.yellowself.purple中的位置和尺寸

//    CGRect newRect = [self.yellow.superview convertRect:self.yellow.frame toView:self.purple];

    

    // 计算self.redself.yellow中的位置和尺寸

    //    CGRect newRect = [self.red convertRect:self.red.bounds toView:self.yellow];

    // 计算self.redself.yellow中的位置和尺寸

//    CGRect newRect = [self.yellow convertRect:self.red.bounds fromView:self.red];

    

    // 计算self.red在屏幕中的位置和尺寸(nil代表屏幕)

   CGRect newRect = [self.redconvertRect:self.red.boundstoView:nil];

    NSLog(@"%@",NSStringFromCGRect(newRect));



// UIPageControl就算没有设置尺寸,里面的内容还是照常显示的

    //    pageControl.width = 100;

    //    pageControl.height = 50;

    //    pageControl.userInteractionEnabled = NO;







如果发现控制器的view还在,但是view上面的数据不显示,极大可能是因为控制器被提前销毁了


/*

     [self setValue:tabBar forKeyPath:@"tabBar"];相当于self.tabBar = tabBar;

     [self setValue:tabBar forKeyPath:@"tabBar"];这行代码过后,tabBardelegate就是HWTabBarViewController

     说明,不用再设置tabBar.delegate = self;

     */

    

   /*

     1.如果tabBar设置完delegate后,再执行下面代码修改delegate,就会报错

     tabBar.delegate = self;


     2.如果再次修改tabBardelegate属性,就会报下面的错误

     错误信息:Changing the delegate of a tab bar managed by a tab bar controller is not allowed.

     错误意思:不允许修改TabBardelegate属性(这个TabBar是被TabBarViewController所管理的)

     */







#warning 默认情况下,scrollView一创建出来,它里面可能就存在一些子控件了

#warning 就算不主动添加子控件到scrollView中,scrollView内部还是可能会有一些子控件










// EdgeInsets: 自切

    // contentEdgeInsets:会影响按钮内部的所有内容(里面的imageViewtitleLabel

       shareBtn.contentEdgeInsets =UIEdgeInsetsMake(10,150, 0, 0);

    

    // titleEdgeInsets:只影响按钮内部的titleLabel

    shareBtn.titleEdgeInsets =UIEdgeInsetsMake(0,10, 0, 0);

    

    // imageEdgeInsets:只影响按钮内部的imageView

//    shareBtn.imageEdgeInsets = UIEdgeInsetsMake(20, 0, 0, 50);

    

    

    

//    shareBtn.titleEdgeInsets

//    shareBtn.imageEdgeInsets

//    shareBtn.contentEdgeInsets










/*

 一个控件用肉眼看不见,有哪些可能

 1.根本没有创建实例化这个控件

 2.没有设置尺寸

 3.控件的颜色跟父控件的背景色一样(实际上已经显示了,只不过用肉眼看不见)

 4.透明度alpha <= 0.01

 5.hidden = YES

 6.没有添加到父控件中

 7.被其他控件挡住了

 8.位置不对

 9.父控件发生了以上情况

 10.特殊情况

 * UIImageView没有设置image属性,或者设置的图片名不对

 * UILabel没有设置文字,或者文字颜色和跟父控件的背景色一样

 * UITextField没有设置文字,或者没有设置边框样式borderStyle

 * UIPageControl没有设置总页数,不会显示小圆点

 * UIButton内部imageViewtitleLabelframe被篡改了,或者imageViewtitleLabel没有内容

 * .....

 11、自切了:UIEdgeInsetsMake

 添加一个控件的建议(调试技巧):

 1.最好设置背景色和尺寸

 2.控件的颜色尽量不要跟父控件的背景色一样

 */


/*

 1.程序启动会自动加载叫做Default的图片

 1> 3.5inch retain屏幕:Default.png

 2> 3.5inch retina屏幕:Default@2x.png

 3> 4.0inch retain屏幕: Default-568h@2x.png


 2.只有程序启动时自动去加载的图片, 才会自动在4inch retina时查找-568h@2x.png

 */


归档

//归档

[[NSUserDefaultsstandardUserDefaults] setObject:currentVersionforKey:key];

//即时刷新

[[NSUserDefaultsstandardUserDefaults] synchronize];









 //将最新的微博数据添加到总数组最前面

       NSRange range = NSMakeRange(0, newStatuses.count);

       NSIndexSet *set = [NSIndexSetindexSetWithIndexesInRange:range];

        [self.statusesinsertObjects:newStatuses atIndexes:set];






//添加刷新控件

    -(void)setupRefresh{

    //添加刷新控件

    UIRefreshControl *refreshControl = [[UIRefreshControlalloc] init];

    //只有用户通过手动下拉刷新,才会触发UIControlEventValueChanged事件

    [refreshControl addTarget:selfaction:@selector(refreshStateChange:)forControlEvents:UIControlEventValueChanged];

    [self.tableViewaddSubview:refreshControl];

    

    //马上进入刷新状态(仅仅是显示刷新状态,并不会触发UIControlEventValueChanged事件)

    [refreshControlbeginRefreshing];

    

    

    //马上加载数据(自己加载)

    [selfrefreshStateChange:refreshControl];

}







/**

 *  显示最新微博数量,弹出一个小框框的效果

 *

 *  @param count 最新微博数量


 //如果某个动画执行完毕后,又要回到动画执行前的状态,建议使用transform来做动画


 */

-(void)showNewStatusCount:(int)count{

    

    //创建label

   UILabel *label = [[UILabelalloc] init];

    label.backgroundColor = [UIColorcolorWithPatternImage:[UIImageimageNamed:@"timeline_new_status_background"]];

    label.width = [UIScreenmainScreen].bounds.size.width;

    label.height =35;

    

    //设置其他属性

   if (count == 0) {

        label.text =@"没有新的微博数据,稍后再试";

    }else{

        label.text = [NSStringstringWithFormat:@"共有%d条新的微博数据",count];

    }

    label.textColor = [UIColorwhiteColor];

    label.textAlignment =NSTextAlignmentCenter;

    label.font = [UIFontsystemFontOfSize:16];

    

   //添加

    label.y =64 - label.height;

    //label添加到导航控制器的view中,并且盖在导航栏下面

    [self.navigationController.viewinsertSubview:labelbelowSubview:self.navigationController.navigationBar];

    

   //动画

    //先利用1s的时间,让label往下移动一段距离

   CGFloat duration = 1.0; //动画时间

    [UIViewanimateWithDuration:duration animations:^{

//        label.y += label.height;

        label.transform =CGAffineTransformMakeTranslation(0, label.height);

    }completion:^(BOOL finished) {

        //延迟一秒后再利用1s的时间让label往上移动一段距离(回到一开始的状态)

       CGFloat delay = 1.0;

        //UIViewAnimationOptionCurveLinear:匀速

        [UIWindowanimateWithDuration:duration delay:delayoptions:UIViewAnimationOptionCurveLinearanimations:^{

//            label.y -= label.height;

            label.transform =CGAffineTransformIdentity;

        }completion:^(BOOL finished) {

           //把自己销毁

            [labelremoveFromSuperview];

        }];

    }];

}

    


原创粉丝点击