智能嘘嘘扣项目总结

1031

1.智能嘘嘘扣立项

2.主流界面搭完参考新浪微博

3.主要技术点(封装自定义tabbar, cell,navgationbar)

4.难点:为方便后期开发通过item 传递模型使后期开发更加省事

5.加入上下水波动态显示:技术难点参考code4App

6.导入音乐铃声:根据MJ音乐播放器加载更多东西

7.通过xib描述登陆和注册界面完成离线登陆版本

8.通过2个string文件完成语言本地化以及调用系统相机,相册本地化操作(在plist文件中完成NSlocation加载语言本地化baidu)

9.通过对铃声处理以及业务逻辑处理完成铃声导入和铃声操作以及NSUserDefault 存储设置本地化操作

10.通过修改部分bug以及对存储和本地化操作以及对控制器生命周期了解如何设计代码

11.彻底研究自定义cell以及完成对item模型封装和如何加载cell上数据通过contentView加载以及对项目小部分重构

12.研究自定义AlertView弹框通过自己定义view让后调用AlertView setValue 方法可以实现往AlertView上面加东西完成多次弹框需求

13.研究进入主界面弹框以及对主界面弹框分析在ViewDidLoad里面实现,那么首先所有的view方法都要调用super 的方法然后其次要在这里写不阻塞线程这是重点所以要分析思路

14.研究如何实时完成ui界面刷新目前采用NSTimer定时器完成时时调用方法完成蓝牙数据的实时传输其次接受数据值如何进行及时更新处理分析

15.在给定义的label 和button 进行赋值操作以及实时刷新操作时处理点语法与button的setter和getter方法使用,因为button有状态之分所以完成对这些操作的处理

16.研究Quart2D绘图以及完成数据实时更新动态显示手绘条DrawRect 方法 和SeedDisPlay方法重绘

17.数据展示上进行修正

18.如何自定义控件研究例如自定义button 那么button 里面有什么属性 image  左边  lable 右边 系统默认是这样,所以自定义的时候继承系统的重写系统的SetLableRect 和 SetImageRect 方法调用super方法然后进行自定义以及修改

19.在控制器进行切换转场的时候有时候会出现有阴影和色调不一致情况 那么在控制加载完毕控制器即将加载完毕这些控制器生命周期方法中实现对backgroundcolor 的处理

20.自定义控件研究

21.对MJ新特性界面研究掌握,然后封装一套完成本地化存储操作的新特性框架提供图片完成新特性且记载本地化版本其次最后一个界面完成点击处理进入主界面

22.在对NSUserDefault 理解创建时候存储加载时候取出 但是重难点:取出之后方法走几次是否实时显示那么该写在什么界面以及通过key 存取什么就是什么 一般用id 接收

23.完成基本功能需求界面搭台处于调试bug 

24.目前通过设定的是根据 // 4s 320 * 480  5s 320 * 568  6 375 * 667 6p 414 * 736 完成对所有手机以及所有界面的适配工作严格要求ui界面美观和界面功能没有bug

25.完成通过对后台数据对接实现网络请求登陆以及在对登陆界面传递值存储和在宝宝中心界面同步问题根据服务器返回值设定相应的存储(难点:存储值会蹦那么打断点以及po 出这些值的全部属性然后用对应的属性接受)

26.对注册界面的值进行约束以及恰当提示,其次完成注册界面回传值到登陆界面让用户完成直接登录通过NSUserDefault 进行存储和接收(难点:这个密码会进行md5加密所以在实现存储和取值时必须在md5加密之前实现存储)

27.本地化实现中英文切换通过2个string文件完成然后在对文件处理过程中一定要完成百分百相对应其次在进行ui排布的时候很多地方和方法要实现numberofline = 0操作实现多行;例如cell和很多地方需要处理

28.本地通知实现那么本地通知写在那里都是可以的之前为什么不出来本地通知呢?首先在本地通知的时候xcode6之前需要加载本地通知证书允许通知xcode实现了本地通知需要在didFinishLaunchingWithOptions 中实现如下方法:

  //iOS8之后推送

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])

    {

        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];

    }

29.[NSThread sleepForTimeInterval:0.25];  完成launchImage延时加载问题

30.宝宝红屁屁界面搭载完毕参考之前所完成的功能秒解但是注意系统顺序以后控制器跳转的问题

31.完成进入界面弹框加载使用引导通过AlertView加载然后AlertView可以自由拖拽其次完成了点击和向下滑动都进入蓝牙连接界面通过block实现

32.完成多次使用提示框操作用户自由设置通过NSUserDefaults 实现存储但是存储时候进行操作以及明确什么位置取然后存储状态和值都不一样所以以及完成与设置界面的双从对接

33.信息同步,登录注册界面约束完成更加人性化设计

34.Xcode->Product->Analyze(command+shift+B) 检查内存泄漏

35.Xcode插件(管理)// http://www.cnblogs.com/Bob-wei/p/4546498.html

1.安装Alcatraz

「安装」

终端输入:

curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

「卸载」

删除插件:

rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/Alcatraz.xcplugin

删除缓存数据:

rm -rf ~/Library/Application\ Support/Alcatraz

36.Xcode(10大值得插件)// http://www.gbtags.com/gb/mobileshare/3709.htm

// http://www.cocoachina.com/industry/20130918/7022.html 

// ~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/  前往Xcode 插件安装包

37.解决Xcode6.4 插件无法运行的bug // http://www.bubuko.com/infodetail-963903.html

38.//页面切换效果设置: // http://blog.sina.com.cn/s/blog_5fb39f910101a64l.html

controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

[self presentModalViewController:controller animated:YES];

//可供使用的效果:

typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

    UIModalTransitionStyleCoverVertical = 0,

    UIModalTransitionStyleFlipHorizontal,

    UIModalTransitionStyleCrossDissolve,

    UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2),

};


typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {

    UIModalPresentationFullScreen = 0,

    UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2),

    UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2),

    UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),

    UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),

    UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),

    UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),

    UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0),

    UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,

};


//恢复之前的页面:

[self dismissModalViewControllerAnimated:YES];

39.UISwitch isOn属性和UIButton selected 属性不一样 所以存储时候要注意(switch 只能通过UIControlEventValueChange 来监听)  

40.归档 NSKeyedArchiver(遵守NSConding协议存所有的对象) NSUserDefaults存储轻量级简单(难点:根据item  title 存储 基本思想 ) [timeDefault synchronize]; 同步方法

41.command + shift + B  内存泄漏检测方式 断点调试 po 然后view 控制器生命周期方法一定要调用super 的方法 不然就会产生内存泄漏(难点:尤其自己手写的时候一定要记得添加)

42.NSUserDefaults 存储对象 或者存储bool int 这之类的东西 首先如何做即时存储 那么存储的东西即时显示 那么我们就要考虑(难点:0.控制器的生命周期 1.存储所取需要的东西其次在存储和取的值之间相互转换问题 2.存储通过什么key\keypath 存储取出时候需要什么取什么) 例如: 本项目进入界面,报警,手动更换尿不湿所进行的操作设置存储和存取不一定要存储每个值每个key 既然通过一个switch 控制这些的按钮的开关 所以 :

/**

     *  如果打开开关执行操作

     */

    if (self.switchView.isOn == YES) {

        /**

         *  取出选择更换状态 然后尝试通过存储key\keypath 清空所存储的选项(难点:switch用法)

         */

        NSUserDefaults *choiceDefaults = [NSUserDefaults standardUserDefaults];

        /*--------清空手动更换尿不湿选项确定的设置-------------*/

        [choiceDefaults removeObjectForKey:@"choiceChange"];

        [choiceDefaults removeObjectForKey:@"choiceNot"];

        

        /*--------清空报警更换尿不湿选项确定的设置-------------*/

        [choiceDefaults removeObjectForKey:@"changeAfter"];

        [choiceDefaults removeObjectForKey:@"changeNow"];

        

        /**

         *  取出viewDidAppear里面的设置(难点:switch用法)

         */

#pragma warning ---- 为什么只能写在这里控制器的生命周期控制器还没加载完毕你就显示所有子控件必然造成线程堵塞

        NSUserDefaults *operationDefaults = [NSUserDefaults standardUserDefaults];

        /*--------清空viewDidAppear设置确定的选项-------------*/

        [operationDefaults removeObjectForKey:@"operation"];

    }

43.设置界面音乐设置界面重构:首先因为播放音乐目前没有找到合适的设置播放音乐时长的问题以及进行压力测试时界面退出音乐还是播放以及会存在闪退情况,(原因:压力测试所设置的currentAudioPlayer 不能单一所以会存在问题,即在播放下个音乐时上个音乐的暂停以及销毁处理不到位) 所以采取音频播放的方式重构该界面 

 /**

 *  当前播放的音乐播放器根据mainbund 来播放 这是合理的

 */

@property (nonatomic, assign) SystemSoundID soundID;


if (!voiceStr) { // 没有设置声音

        if (button.tag == 11) {

// 1.加载音效文件(短音频)

// 1个音效文件  对应 1 SoundID

            SystemSoundID soundID1; 

            NSURL *url = [[NSBundle mainBundle] URLForResource:@"宝宝笑了_5.mp3" withExtension:nil];

            AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID1);

            

            // 拿到音效ID播放

            AudioServicesPlaySystemSound(soundID1);

            self.soundID = soundID1;


        } else if (button.tag == 12) {

// 调用系统振动方法

            AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

        } else {

            SystemSoundID soundID1;

            NSURL *url = [[NSBundle mainBundle] URLForResource:@"宝宝笑了_5.mp3" withExtension:nil];

            AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID1);

            

            // 拿到音效ID播放边播放边振动

            AudioServicesPlayAlertSound(soundID1);

            self.soundID = soundID1;

        }


然后由于设置界面 同时做了 3个NSUserDefaults 操作存储 且通过简单存储NSString 或者bool值就行 这样 我们在判断的时候可以通过switch case : 或者if  else if 来做判断 (难点:不至于会导致长值或者不走方法的现象 这点需要注意)

其次再判断的时候通过先判断类型决定怎么播放 其次根据音乐 和时长来选择相应的音频文件 (3!种考虑选项) 

44.在输入文字 例如lable 或者button.titleLable.text  这样的设置的时候 numberOflines = 0 这样的操作时候换行 那么在AlertView 中文字 我们要实现换行功能也可以在文字中 手动加入\n 这样转译符号

45.为什么要设置这些tag 因为你通过NSUserDefaults 存储所以你必须合理设置和记住这些值  不然程序运行就行崩溃 当你改动tag 值必须要卸载程序 和清除缓存才能保证程序不崩溃 所以准确来说这是一个不太合理的设计模式

/**

 *  设置界面tag

 *  type(类型): 11 12 13

 *  time(时长): 21 22 23

 *  sound(音频): 31 32 33 34 35

 *  lx(天气): 41 42 43

 *  进入界面用户操作选择存储: 51 52 (无论有无煎熬时间都需要弹框所以这样设置)

 *  报警后用户操作设置存储: 61 62 

 *  报警频率设定: 71 72 73

 *  代理设置tag 通过type  enum 的方式去实现: 例如主界面的homeMainView 代理传出

 *

 *  typedef enum {

 *   JKHomeMainViewButtonXuxuTimes,

 *   JKHomeMainViewButtonRangeOfParents,

 *   JKHomeMainViewButtonLinkBlueTooth,

 *   JKHomeMainViewButtonTormentTime,

 *   JKHomeMainViewButtonPpOdds

 *   } JKHomeMainViewButtonType;

 *

 *   @class JKHomeMainView;

 *   @protocol JKhomeMainViewDelegate <NSObject>

 *   @optional

 *   - (void)homeMainViewDidClickedCircleButton:(UIButton *) button Type:(JKHomeMainViewButtonType)type;

 *

 *   @end

 */

46.@synthesize 合成语法 //   http://blog.csdn.net/zhiganglet/article/details/7546333

@代表“Objective-C”的标志,证明您正在使用Objective-C;

    Objective-C语言关键词,@property@synthesize配对使用。

    功能:让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。

47.获取当前正在使用的版本(难点:例如我们根据正在使用语言设置相关的界面设置不同的界面例如中英文转换的时候UI界面不一致可以根据正在使用语言设置2个frame) 

    /**

     *  获取当前的语言版本

     */

    NSArray *languages = [NSLocale preferredLanguages];

    NSString *currentLanguage = [languages objectAtIndex:0];

    NSLog ( @"%@" , currentLanguage);


    if ([currentLanguage isEqualToString:@"zh-Hans"]) {

        self.textLabel.text = music.numberSound;

        self.detailTextLabel.text = music.name;

    } else if ([currentLanguage isEqualToString:@"en"]) {

        self.textLabel.text = music.numberSoundE;

        self.detailTextLabel.text = music.nameE;

    }

48.改项目名称和软件名称:

单击项目(改名称)—>Rename—>enable—>contiue 

Manage Schemes..—> 单击名称—> 点空白—>ok 

49.我们在使用SQL的时候我们应该手动导入SQL3的框架frameWorking FMDB OC的方式等装了SQLite的C语言API

FMDB 三个主要的类:

FMDatabase —> 一个对象代表一个单独的SQLite数据库 (用来执行SQL语句)

FMResultSet —> 使用FMDatabase 执行查询后的结果集

FMDatabaseQueue —> 用于在多线程中执行多个查询或更新,它是线程安全的(即不会产生资源抢夺,死锁等情况)

/**

     *  path 三种情况

     *  1.具体的文件路径:找到具体的文件路径,如果不存在自动创建

     *  2.空字符串@"" nil 的区别 @"" 还是一个对象

     *   >会在临时目录创建一个空的数据库

     *   >FMDatabase连接关闭时,数据库文件也会被删除

     *  3.nil: 会创建一个内存中的临时数据库,FMDatabase 连接关闭时,数据库会被销毁

     */

    FMDatabase *db = [FMDatabase databaseWithPath:path];

    if (![db open]) {

        NSLog(@"数据库打开失败!!!");

    }

50.数据库操作:我们做移动端开发,打开数据库后就长期打开不要轻易关闭,而服务器端则不一样,则是使用的时候就打开,使用完毕就关闭,下次使用再次打开!既然要长期打开 我们就应该更加面向对象用OC的语法 用一个strong 引用就行

51.Show the Breakpoint navigator 全局断点 [—]> 

52.使用kvc 和kvo 的区别kvc 键值编码 kvo 则可以监听任何对象的事件 使用kvo 的时候 一定要调用dealloc 析构方法来手动释放 避免野指针错误

53.这个是蓝牙开发那么如何保持蓝牙在后台一直运行呢?(难点:Capabilities —> Background Modes —> ON —> Bluetooth 选项)

54.目前服务器端大的数据库Oracle dbq 而MySQL比较轻量级  // http://zhidao.baidu.com/link?url=Ldq-FbKLDec-oltXrbgY2YXUdlJfg5_UXECrU5LZ-gnURhjsEOOKfMuvFWWZY8En_57qM9QbFkZkeutiVoQYBQXMyzNcw5A2yvhThZ_7ucq

55.数据库是关系型数据库:意为表1、表2的相互关系 而对象型则直接扔对象进去 作为一张表:肯定有主键 id 而且是自动增长的这是规范 // http://blog.csdn.net/robinjwong/article/details/18502195

56.http://code.cocoachina.com 开发中中心

57.数据缓存思想:例新浪微博 

—> 存模型:IWStatus—>NSData以blob形式存储  [NSKeyArchiver archivedDataWithrootObject:id];

—>直接存Json[@“Statues”]—>对应微博对象    .. 必须遵守NSCoding 协议

58.bolck 全局变量 写在外面 不能使用点语法 一次创建写在initialize里面

#import "IWStatusCacheTool.h"

#import "IWAccount.h"

#import "IWAccountTool.h"

#import "FMDB.h"


@implementation IWStatusCacheTool


static FMDatabaseQueue *_queue;


+ (void)initialize

{

    // 0.获得沙盒中的数据库文件名

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"statuses.sqlite"];

    

    // 1.创建队列

    _queue = [FMDatabaseQueue databaseQueueWithPath:path];

    

    // 2.创表

    [_queue inDatabase:^(FMDatabase *db) {

        [db executeUpdate:@"create table if not exists t_status (id integer primary key autoincrement, access_token text, idstr text, dict blob);"];

    }];

}


+ (void)addStatuses:(NSArray *)dictArray

{

    for (NSDictionary *dict in dictArray) {

        [self addStatus:dict];

    }

}


+ (void)addStatus:(NSDictionary *)dict

{

    [_queue inDatabase:^(FMDatabase *db) {

        // 1.获得需要存储的数据

        NSString *accessToken = [IWAccountTool account].access_token;

        NSString *idstr = dict[@"idstr"];

        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];

        

        // 2.存储数据

        [db executeUpdate:@"insert into t_status (access_token, idstr, dict) values(?, ? , ?)", accessToken, idstr, data];

    }];

}


+ (NSArray *)statuesWithParam:(IWHomeStatusesParam *)param

{

    // 1.定义数组

    __block NSMutableArray *dictArray = nil;

    

    // 2.使用数据库

    [_queue inDatabase:^(FMDatabase *db) {

        // 创建数组

        dictArray = [NSMutableArray array];

        

        // accessToken

        NSString *accessToken = [IWAccountTool account].access_token;

        

        FMResultSet *rs = nil;

        if (param.since_id) { // 如果有since_id

            rs = [db executeQuery:@"select * from t_status where access_token = ? and idstr > ? order by idstr desc limit 0,?;", accessToken, param.since_id, param.count];

        } else if (param.max_id) { // 如果有max_id

            rs = [db executeQuery:@"select * from t_status where access_token = ? and idstr <= ? order by idstr desc limit 0,?;", accessToken, param.max_id, param.count];

        } else { // 如果没有since_idmax_id

            rs = [db executeQuery:@"select * from t_status where access_token = ? order by idstr desc limit 0,?;", accessToken, param.count];

        }

        

        while (rs.next) {

            NSData *data = [rs dataForColumn:@"dict"];

            NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];

            [dictArray addObject:dict];

        }

    }];

    

    // 3.返回数据

    return dictArray;

}

59.FMDB 增删查改 然后 事务和多线程中FMDB的使用 要使用  @property (nonatomic, strong) FMDatabaseQueue *queue; // 经典案例:银行存款俩个人同时操作一个账号  // 事务的概念:银行 一系列操作如果中间某项出错那么回滚 

#import "IWViewController.h"

#import "FMDB.h"


@interface IWViewController ()

@property (nonatomic, strong) FMDatabaseQueue *queue;

- (IBAction)insert;

- (IBAction)update;

- (IBAction)delete;

- (IBAction)query;

@end


@implementation IWViewController


- (void)viewDidLoad

{

    [super viewDidLoad];

    

    // 0.获得沙盒中的数据库文件名

    NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"student.sqlite"];

    

    // 1.创建数据库队列

    self.queue = [FMDatabaseQueue databaseQueueWithPath:filename];

    

    // 2.创表

    [self.queue inDatabase:^(FMDatabase *db) {

        BOOL result = [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer);"];

        

        if (result) {

            NSLog(@"创表成功");

        } else {

            NSLog(@"创表失败");

        }

    }];

}


- (IBAction)insert

{

    [self.queue inDatabase:^(FMDatabase *db) {

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

            NSString *name = [NSString stringWithFormat:@"rose-%d", arc4random() % 1000];

            NSNumber *age = @(arc4random() % 100 + 1);

            [db executeUpdate:@"insert into t_student (name, age) values (?, ?);", name, age];

        }

    }];

}


- (IBAction)update

{

    [self.queue inDatabase:^(FMDatabase *db) {

        // 开启事务

//        [db executeUpdate:@"begin transaction;"];

//        [db beginTransaction];

        

        [db executeUpdate:@"update t_student set age = ? where name = ?;", @20, @"jack"];

        [db executeUpdate:@"update t_student set age = ? where name = ?;", @20, @"jack"];

        

        

//        if (发现情况不对){

//            // 回滚事务

//            [db rollback];

////            [db executeUpdate:@"rollback transaction;"];

//        }

        

        

        [db executeUpdate:@"update t_student set age = ? where name = ?;", @20, @"jack"];

        

        // 提交事务

//        [db commit];

//        [db executeUpdate:@"commit transaction;"];

    }];

}


- (IBAction)delete

{

    [self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) {

        [db executeUpdate:@"update t_student set age = ? where name = ?;", @20, @"jack"];

        [db executeUpdate:@"update t_student set age = ? where name = ?;", @20, @"jack"];

        

//        if (发现情况不对){

//            // 回滚事务

//            *rollback = YES;

//        }

    }];

}


- (IBAction)query

{

    [self.queue inDatabase:^(FMDatabase *db) {

        // 1.查询数据

        FMResultSet *rs = [db executeQuery:@"select * from t_student where age > ?;", @50];

        

        // 2.遍历结果集

        while (rs.next) {

            int ID = [rs intForColumn:@"id"];

            NSString *name = [rs stringForColumn:@"name"];

            int age = [rs intForColumn:@"age"];

            

            NSLog(@"%d %@ %d", ID, name, age);

        }

    }];

}

60.数据缓存Pasted Graphic.tiff

61.自定义searchBar 


#import "JKSearchBar.h"


@interface JKSearchBar : UITextField

+ (instancetype)searchBar;

@end


#import "UIImage+JK.h"


@implementation JKSearchBar

+ (instancetype)searchBar

{

    return [[self alloc] init];

}


- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        // 背景

        self.background = [UIImage resizeImageWithImageName:@"searchbar_textfield_background"];

        self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;

        // 左边的放大镜图标

        UIImageView *iconView = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"searchbar_textfield_search_icon"]];

        iconView.contentMode = UIViewContentModeCenter;

        self.leftView = iconView;

        self.leftViewMode = UITextFieldViewModeAlways;

        

        // 字体

        self.font = [UIFont systemFontOfSize:13];

        

        // 右边的清除按钮

        self.clearButtonMode = UITextFieldViewModeAlways;

        

        // 设置提醒文字

        NSMutableDictionary *attrs = [NSMutableDictionary dictionary];

        attrs[NSForegroundColorAttributeName] = [UIColor grayColor];

        self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"搜索", nil) attributes:attrs];

        

        // 设置键盘右下角按钮的样式

        self.returnKeyType = UIReturnKeySearch;

        self.enablesReturnKeyAutomatically = YES;

    }

    return self;

}


- (void)layoutSubviews

{

    [super layoutSubviews];

    

    // 设置左边图标的frame

    self.leftView.frame = CGRectMake(0, 0, 30, self.frame.size.height);

}

62.点击模拟器之后进行还原设置(当模拟器无法上网的时候我们可以选择还原设置)

63.BOOL类型的定义 在一些block中我们起初定义BOOL的值然后在block中回调这个方法  * BOOL 指向 bool类型的指针 如果我们要停止这个遍历那么让* BOOL  = YES; (算是运行时的一个机制)

64.我们想要将对象直接存到一个文件路径中的时候会出现问题因为存对象我们必须遵守<NSCoding>协议 

#import "MJExtension.h" 


MJCodingImplementation (又一强大的MJ语法)


- (void)encode:(NSCoder *)encoder

{

//    [self encode:encoder];

   /**

     *  归档所有对象 相当于调用上面代码 封装完毕

     *

     *  @param ivar 遍历所有要存储的对象

     *  @param stop BOOL类型的定义 在一些block中我们起初定义BOOL的值然后在block中回调这个方法

  *  BOOL 指向 bool类型的指针 如果我们要停止这个遍历            

     *  那么让* BOOL  = YES; (算是运行时的一个机制)

     */

    [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) {

        [encoder encodeObject:ivar.value forKey:ivar.propertyName];

    }];

}


- (id)initWithCoder:(NSCoder *)decoder

{

//    [self decode:decoder];


    if (self = [super init]) {

        [self enumerateIvarsWithBlock:^(MJIvar *ivar, BOOL *stop) {

            ivar.value = [decoder decodeObjectForKey:ivar.propertyName];

        }];

    }

    return self;

}

65.我们在存储数据的时候会调用getter setter方法那么归档数据的时候我们要避免重写getter setter方法可以在对成员变量进行限制(readonly 只读这些属性然后那显示)

66.想为宝贝选购的心锁 // https://ctf.tmall.com/search.htm?spm=a1z10.1-b.w5003-9699441364.14.mhp5Qr&mid=w-2375614900-0&keyword=%B2%AC%BD%F0++%B5%F5%D7%B9&search=y&orderType=hotsell_desc&tsearch=y&scene=taobao_shop 

67.Xcode 6 增加pch文件  // http://www.aiweibang.com/yuedu/2938187.html

68.苹果开发者中心我们登陆时候显示问题\\ ANNOUNCEMENT: Updated Program License Agreement解决办法

// http://www.weste.net/2011/6-7/Review-Agreement.html

69.苹果开发者账号注册流程 // http://jingyan.baidu.com/article/4dc408489ebbb2c8d946f12c.html

70.真机调试安装过程 // 

71.关于Xcode配置窗口配置文件,Xcode真机调试出现如下问题:0xE8008018 // http://www.07net01.com/2015/07/886918.html

72.调试过程中出现的小bug无法正常运行进行Debug // http://shizhifang886.blog.163.com/blog/static/30585110201482912125657/

73.在传值过程中,尝试通过UIApplication 和 全局变量来传值但是值传为空 这个问题有待研究???

74.事件传递者方法如何知道你点击是那个view

/**

 *  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;   // recursively calls - pointInside:withEvent:. point is in the receiver's coordinate system

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;   // default returns YES if point is in bounds

 *

 *  事件传递者方法

 */

75.UISplitViewController的简单使用  // http://www.2cto.com/kf/201409/330286.html 

76.[self presentViewController:nil animated:YES completion:^{

        

    }];[self.navigationController pushViewController:whrite animated:YES]; 的区别一个算是modal视图而另外一个则是导航控制器方法 所以在销毁这个控制器在控制器出栈的时候所调用的方法也不相同

  [self dismissViewControllerAnimated:YES completion:^{

        

    }];[self.navigationController popViewControllerAnimated:YES];

77.谷歌浏览器自动拦截广告插件 //

78.真机调试过程中出现"The identity used to sign the executable is no longer valid"  // http://blog.csdn.net/rekrad/article/details/17860117 不是证书的问题,是Xcode 配置有问题

79.在一个控件传递他的userInteractionEnabled属性时候,如果作为代理已经将这个事件传递出去那么你无论何时监听它的事件改变都没有用,只有将这个按钮的状态传出去根据状态来显示这个按钮是否可以被点击

80.Xcode插件网址都是对的 每次更新Xcode 插件也会更新那么你依旧点击网址重新更新改info.plist中的一个item就行

81.如何实现iOS开发中边播放音乐边震动// http://blog.sina.com.cn/s/blog_68661bd80101d2bj.html

82.iOS开发小技巧之提示音播放与震动 // http://www.2cto.com/kf/201401/270419.html

83.iOS边播放音乐边震动 // http://blog.csdn.net/u011238639/article/details/45673591

84.通知中心使用方法 // http://blog.csdn.net/dqjyong/article/details/7678108

85.iOS开发系列— 通知与消息机制 1>本地通知 2>推送通知 3>iOS开发证书、秘钥 4>通知中心  //  http://www.cnblogs.com/kenshincui/p/4168532.html

86.Xcode快捷键大全  // http://www.360doc.com/content/12/0521/09/6541311_212458595.shtml

87.Xcode数据显示在控制台 // http://blog.csdn.net/majiakun1/article/details/43113577

88.UISwitch 用法小技巧 :

/**

 *  实时显示开关的记录并且根据调用layer动画

 *  UISwitch 技巧

 *  1> 监听UISwitch 只能够是 UIControlEventValueChanged 因为它只有YES\NO属性

 *  2> 实时设置UISwitch 开关属性的时候只能调用self.dismissSwitch.on(不能调用isOn)

 */

89.









新版本新的开端 :网络数据处理 

1.将本地数据库东西上传到服务器:// http://bbs.csdn.net/topics/390145929

2.如何将本地的MYSQL数据库上传到服务器http://blog.csdn.net/lishimin1012/article/details/16361913

3.做的项目涉及到服务器,将项目上传到服务器上:// http://www.iteye.com/problems/63590

4.网页数据库上传到服务器// http://www.chuangluo.com/news_268.html

5.Xcode升级 插件失效快速解决方式 命令行解决所有Xcode插件问题  屌屌屌 // http://www.th7.cn/Program/IOS/201507/495407.shtml

6.

你可能感兴趣的:(UI,技术,开发,本地化,音乐)