音乐播放器

 

 

5.1  微博 (ok) 好友列表(no ) 好友对话(ok),团购(ok)  再敲一遍

5.3: 汤姆猫,传智猜图的逻辑,缩放(ok),轮播(待研究),英雄列表,汽车展示重新敲

5.4: 把以前做的思路理一理;

5.5: 预习一下;

 

ios校招:

主要是c,c++  (很少有问ios的,项目问的很简单,只有网易问的是iOS的)

智力题:1-100之间的怎么样的找一个数最快;

c,c++问的是算法,数据结构;

找工作的帖子;分享找工作;

 

面试很少问UI  问多线程_retian _ 内存管理

GCD  和NSOperation

 

 

 

编码规范??良好的

 

 

 

 

 

qq好友列表的headerView和团购的headerView有什么区别

qq好友列表的类似于加在组的最开头,和加入cell的形式类似

团购加在:头部就相当于加个工具条

 

 

 

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import <UIKit/UIResponder.h>

#import <UIKit/UIInterface.h>

#import <UIKit/UIKitDefines.h>

#import <UIKit/UIAppearance.h>

#import <UIKit/UIDynamicBehavior.h>

#import <UIKit/NSLayoutConstraint.h>

UI基础笔记

无**   一般知识点

***  重点

***** 重难点  编码规范存在的问题:  ==  *  空格,别人阅读方便

 

UI笔记

按钮能够显示lable和图片是应为按钮内部有UIlable,UIImageView//不是UIView

所以可以显示图片和文字

按钮有normal 和highlight 还有其他diasble;

字典代表数据,根据名称找到数据,适合存储大规模的数据.

字典的缺点:通过字符串类型的key取值容易写错,写错了key编译器不会报错;

模型:存放数据,继承自NSObject比较纯洁的对象;

创建一个类(即模型)MJApp.h+MJApp.m;只用来放数据,比较纯洁;

上述类成为模型类;

12个字典转化为12个模型,//每个字典中有两对数据;

在模型对象中声明两个属性Name,和icon存储数据;

存储的每个数据是一个字典;name

自定义构造方法都是返回:Id类型,是自定义类型;//intancetype

 

 

UI基础笔记

 

0416:UI 基础

IOS 4.0  iphone,开发高峰期

ios6.0真正的是多任务运行,界面是

 

1.IBAction:

1> 能保证方法可以连线

2> 相当于void

 

 

2.IBOutlet:

1> 能保证属性可以连线

 

3.常见错误

setValue:forUndefinedKey:]: this class is not key value coding

错误原因是:连线出问题了

 

4.Xcode5开始的一些建议

把用于连线的一些方法和属性声明在.m文件的类扩展中,保证了封装性,私有的;

 

5. frame\center\bounds

1> frame:能修改位置和尺寸

2> center:能修改位置

3> bounds:能修改尺寸(x\y一般都是0)相对于自己:

0404

identifier:com.baidu,cn.itcast,公司域名

name名字中不能出现中文;

prefix

入口是main函数,

 

UIView--画板

UIViewController====画家;先创建UIController再画板,画家管理画板

IBAction  相当于void告诉编译器这个是可以连线的

控件使用@property   weak

 

显示字符串的的控件一定有text的属性,text的方法

第一响应者:当前和谁交互谁就是第一响应者

[self.view endEditing:YES];

self.view不当第一响应者   //view 里面包含有UILable UIview UIButton 至少这三种

//这三种都不当第一响应者

 

/*self问题总结*/

XiaoMing  类

创建xiaoming 对象;

小明类中有name,age,delegate 个属性;

sick方法是XiaoMing类中定义方法

-(void)sick

{

NSLog(@"生病了");

[_delegate lookSickWithName:_name andAge:_age];

//_name=self.name    _age=self.age,此处是xiaoming这个对象调用

//name的get方法不是,self不代表_delegate这个对象,[]这不算一个方法

//self调用当前的方法;

[_delegate lookSickWithXiaoMing:self];//此方法如果不实现就会崩溃

}

self关键字代表谁?

对象调用self就代表对象

类名调用方法,self就代表那个类

self处在那个类文件中,self就代表那个文件中,直接使用self能访问所在类文件中的方法和

属性,在类中就代表类对象,在类方法中就代表类;

controlviewer类中的对象系统自己创建的,隐藏的!

其实,每当显示一个新界面时,首先会创建一个新的UIViewController对象,然后创建一个对应的

全屏UIView,UIViewController负责管理这个UIView   UIViewController就是UIView的大管家,

负责创建、显示、销毁UIView,负责监听UIView内部的事件,负责处理UIView与用户的交互

 

 

 

UIViewController内部有个UIView属性,就是它负责管理的UIView对象 ,监听按钮:

@property(nonatomic,retain) UIView *view;//所以可以self.view

//计算器中的所谓的self就是这个view吗,不是这个,self是NJControlView*的对象;

//self.view指的是contrller的子空间下属的view包含的加进去的所有子控件;

//self.text1.此处的self点的覆盖的范围的吗?

 

 

 

 

//view中的所有子空间都不当响应者了

连线的多种方式?

1.从代码拖到界面上

2.从界面拖到代码

3.从control到界面

 

 

1>UIViw所有控件的父控件;

2>frame:控件相对于父类的坐标位置,

3>center:也是以父控件作为参考点

4>bounds:以自己为参考点

 

 

 

self.tupian.frame.origin.x-=10;//错误修改x的值的方法;

CGRect tem=self.tupian.frame;   1>保存原值;

tem.origin.y-=30;               2>修改某一个值

self.tupian.frame=tem;          3>修改的值整体重赋

 

可以得出一个结论:UI界面上的每一个元素都是一个对象,比如:

一张图片是一个UIImageView对象

一段文字是一个UILabel对象//+ =

文本输入,键盘输入:UITexTFeild

一只按钮是一个UIButton对象//文字,图片,响应事件

 

为了方便开发者开发出强大的功能,苹果提供了各种各样的框架

UIKit - 创建和管理应用程序的用户界面

QuartzCore -提供动画特效以及通过硬件进行渲染的能力

CoreGraphics -提供2D绘制的基于C的API

CoreLocation -使用GPS和WIFI获取位置信息

MapKit -为应用程序提供内嵌地图的接口

AVFoundation – 音频处理//等等

 

在.m中声明的方法是私有方法,外界无法直接访问,保证了封装性

int num2 = [self.number2.text intValue];//强制类型装换,self代表.

Perosn *p =(Perosn *)stu;//此处也是强制类型转换,stu本来是Student类型的,强转后转化为Person类型的

疑问:子类是可以强制转化为父类!

 

 

屏幕上能看得见摸得着的东西就是UIView,比如屏幕上的按钮、文字、图片

 

一般翻译叫做:视图\控件\组件

UIButton、UILabel、UITextField都继承自UIView

每一个UIView都是一个容器,能容纳其他UIView(比如右图中的整个键盘是一个UIView,里面容纳很多

小格子的数字UIView)

 

 

严格来讲,下图箭头所指的应该是一个UIViewController对象(手机下方的viewcontriller条),

里面白色的界面仅仅是UIViewController内部的UIView属性(整个白屏,什么都不建时的白屏);

 

 

 

****

综合分析,可以得出程序的简单运行流程是怎么样的?

1>读取Main.storyboard文件

2>创建箭头所指的MJViewController对象

3>根据storyboard文件中描述创建MJViewController的UIView对象

4>将UIView对象显示到用户眼前

现在已经知道:应该由MJViewController来监听“计算”按钮的点击

 

 

 

换句话说,MJViewController应该提供一个方法出来,当用户点击“计算”按钮时,就调用这个方法来

通知MJViewController按钮被人点了MJViewController就在这个方法中实现想做的任何事情,比如

计算2个文本输入框内值的和

 

IBAction

从返回值角度上看,作用相当于void

只有返回值声明为IBAction的方法,才能跟storyboard中的控件进行连线

 

IBOutlet

只有声明为IBOutlet的属性,才能跟storyboard中的控件进行连线

resignFirstResponder//辞职当第一响应者;

当叫出键盘的那个控件(第一响应者)调用这个方法时,就能退出键盘

 

[self.view  endEditing:BOOL];

只要调用这个方法的控件内部存在第一响应者,就能退出键盘

 

 

可见,确实需要经常修改控件状态

那如何去修改控件的状态呢?方法很简单

每一个UI控件都是一个对象//万物皆对象,万物截指针

修改UI控件的状态,其实就是修改控件对象的属性

比如修改UILabel显示的文字,就修改UILabel对象的text属性即可

比如修改UIImageView显示的图片,就修改UIImageView对象的image属性即可

 

不难想到,每一个UI控件肯定都有很多属性,比如:

UIProgressView进度条控件有progress属性(进度值)

UILabel和UITextField都有text属性(显示文字)

UITextField 输入文本

 

虽然,每一个UI控件都有 自己的独特属性,但是有些属性是每个UI控件都具备的,

比如每一个UI控件都有自己的位置和尺寸、都有自己的父控件、子控件。于是,所有的UI控件

最终都继承自UIView,UI控件的公共属性都定义在UIView中,比如:

frame :位置和尺寸

center :中心点位置

 

 

****

@property(nonatomic,readonly) UIView *superview;

获得自己的父控件对象//父控件只有一个

@property(nonatomic,readonly,copy) NSArray *subviews;

获得自己的所有子控件对象//子空间有很多

@property(nonatomic) NSInteger tag;//

控件的ID\标识,父控件可以通过tag来找到对应的子控件

@property(nonatomic) CGAffineTransform transform;

控件的形变属性(可以设置旋转角度、比例缩放、平移等属性)

@property(nonatomic) CGRect frame;

控件所在矩形框在父控件中的位置和尺寸(以父控件的左上角为坐标原点)

@property(nonatomic) CGRect bounds;

控件所在矩形框的位置和尺寸(以自己左上角为坐标原点,所以bounds的x\y一般为0)

//bound也有x,y,w,h   只是相对于自己的来说所以x,y一般都为0;

@property(nonatomic) CGPoint center;

控件中点的位置(以父控件的左上角为坐标原点)

//自己的位置是以中点到父控件的边缘位置

 

****

如果发现通过代码无法修改控件的位置或者尺寸时,应该去掉storyboard里面的autolayout功能,

这是自iOS6开始出现的特性顾名思义,autolayout是用来自动布局的,用来束缚控件的位置和尺寸。

去掉这个功能,控件的位置和尺寸就不再有一些固定的束缚。

 

 

 

1>normal(普通状态)

默认情况(Default)

对应的枚举常量:UIControlStateNormal

2>highlighted(高亮状态)

按钮被按下去的时候(手指还未松开)

对应的枚举常量:UIControlStateHighlighted

3>disabled(失效状态,不可用状态)

如果enabled属性为NO,就是处于disable状态,代表按钮不可以被点击

对应的枚举常量:UIControlStateDisabled

 

设置按钮在不同状态下的背景图片

(为了保证高亮状态下的图片正常显示,必须设置按钮的type为custom)

 

通过以下属性可以修改控件的位置

frame.origin

center

 

通过以下属性可以修改控件的尺寸

frame.size

bounds.size

 

实际上,UIButton自带了很多种不同的样式

 

在用代码创建按钮的同时指定按钮样式

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

UIButtonTypeCustom:无类型,按钮的内容需要自定义

UIButtonTypeDetailDisclosure:

UIButtonTypeInfoLight:

UIButtonTypeInfoDark:

UIButtonTypeContactAdd:(添加一个加号)

 

计算器总结:

1>拖控件

2>controlviewer.m中声明空间的属性,(私有保证封装)

3>controlviewer.h 中声明方法,.m中实现方法,并且 拖线,所有的都要拖线

4>方法中或者字符串的值,字符串装换到int 再输出到显示上

 

 

 

 

+ (NSBundle *)mainBundle;//此处返回的是NSBoudle型的对象;不是返回一个类,返回的对象调用pathfor

个人理解字典:字典也是一种数组类型,只是其中更具key的值就可以找到value的值,key -value一一对应;

字典中存放的方法:

dic {

1 = one;

12 = onew;

13 = onewe;

}

UIButton*   //下面的方法如何去分析,UIButton中如何去找font//用多了就会了?

因为UIButton有font的属性,既然是属性,就需要用对象调用,所以需要对象,对象涉及到get和set方法,

字体返回为UIFont   到UIfont中看看哪些返回UIFont的方法;

 

 

****//手动添加button中的字体

downloadBtn.titleLabel.font=[UIFont systemFontOfSize:12];

//代码添加的控件的层次,结构关系,Xcode可以看到吗?

看不到,因为代码编译,链接后才能展现 ;

 

 

 

//+++++++**********++++++++**********---重点代码

---------------------------------------------------------------------------------------------------

添加代码?

for (int index=0; index<self.apps.count; index++) {//self.apps放回的是一个NSArray;计算NSArray.count

// 3.1.创建1小框框----------------------------

//创建一个大的UIView;UIView和UIImageView的区别,

UIView是UIImageView 的父类;

 

UIView是

UIView*appView=[[UIView alloc]init];               //+++++++**********++++++++**********

// 设置背景色

appView.backgroundColor=[UIColor cyanColor];

// 3.2.计算框框的位置

// 计算行号和列号

int row=index/totalColumns;

int col=index%totalColumns;

// 计算x和y

CGFloat appX=marginX+col*(appW+marginX);

CGFloat appY=marginY+row*(appH+marginY);

//设置Frame的大小和位置

appView.frame=CGRectMake(appX, appY, appW, appH);

//3.3添加框框到控制器

[self.view addSubview:appView];     //此处的view是代表(UIView*);              //+++++++**********++++++++**********

//    有个view的get方法

//3.4UIView中添加内部小控件

 

//3.4.0index位置对应的应用信息

// ****  数组的位置转化为字典;

NSDictionary*appInfo=self.apps[index];//apps声明的是一个数组的属性;对应位置的数组的转化为对应位置的字典;

 

//添加图片----------------------------

//创建+大小+增加+++++++++++

UIImageView*iconView=[[UIImageView alloc]init];  //+++++++**********++++++++**********

CGFloat iconW=45;

CGFloat iconH=45;

CGFloat iconX=(appW-iconW)*0.5;

CGFloat iconY=0;

iconView.frame=CGRectMake(iconX, iconY, iconW, iconH);

//添加图片******  取得字典中icon对应的图片;

iconView.image=[UIImage imageNamed:appInfo[@"icon"]];//+++++++**********++++++++**********

//创建好的子控件添加

[appView addSubview:iconView];

 

 

//添加名字----------------------------

//创建+大小+增加+++++++++++

UILabel*nameLable=[[UILabel alloc]init];

CGFloat nameX=0;

CGFloat nameY=iconY+iconH;

CGFloat nameW=appW;

CGFloat nameH=20;

nameLable.frame=CGRectMake(nameX, nameY, nameW, nameH);

//添加名字******

nameLable.text=appInfo[@"name"];                    //+++++++**********++++++++**********

nameLable.font=[UIFont italicSystemFontOfSize:13];

nameLable.textColor=[UIColor darkGrayColor];

nameLable.textAlignment=NSTextAlignmentCenter;      //+++++++**********++++++++**********

//创建好的子控件添加

[appView addSubview:nameLable];//向UIView对象中增加子控件;

 

 

//添加下载按钮----------------------------

//创建+大小+增加+++++++++++

UIButton*downloadBtn=[[UIButton alloc]init];

CGFloat downloadX=12;

CGFloat downloadY=nameY+nameH;

CGFloat downloadH=20;

CGFloat downloadW=appW-2*downloadX;

downloadBtn.frame=CGRectMake(downloadX, downloadY, downloadW, downloadH);

//创建图片对象

UIImage*normalImage=[UIImage imageNamed:@"buttongreen"];           //+++++++**********++++++++**********

UIImage*highImage=[UIImage imageNamed:@"buttongreen_highlighted"]; //+++++++**********++++++++**********

//将创建的图片对象设置为背景

[downloadBtn setBackgroundImage:normalImage forState:UIControlStateNormal];//+++++++**********++++++++**********

[downloadBtn setBackgroundImage:highImage  forState:UIControlStateHighlighted];//+++++++**********++++++++**********

//设置状态的下载;

[downloadBtn setTitle:@"下载" forState:UIControlStateNormal];//+++++++**********++++++++**********

//设置字体

downloadBtn.titleLabel.font=[UIFont systemFontOfSize:13];//+++++++**********++++++++**********

//创建好的子控件添加

[appView addSubview:downloadBtn];

}

 

-----------------------------------------------------------------------------------------------------------------

------------------------------------------

 

 

MJApp.h文件中模型的头文件中

@property (nonatomic, copy) NSString *name;

/**

*  图标

*/

@property (nonatomic, copy) NSString *icon;

 

/**

*  通过字典来初始化模型对象

*

*  @param dict 字典对象

*

*  @return 已经初始化完毕的模型对象

*/

- (instancetype)initWithDict:(NSDictionary *)dict;

 

+ (instancetype)appWithDict:(NSDictionary *)dict;

------------------------------------------

MJApp.m 中

@implementation MJApp

- (instancetype)initWithDict:(NSDictionary *)dict

{

if (self = [super init]) {//使用%@打印

//字典中name键值对应的名字如:节奏大师赋值给模型的name,模型中声明有name 的get方法;

self.name = dict[@"name"];//self.name = 节奏大师

//字典中icon键值对应的名字如:icon_05赋值给模型的icon,模型中声明有icon的 get方法;

self.icon = dict[@"icon"];//self.icon = icon_05

}

return self;(self 代表MJApp*对象)

}

 

+ (instancetype)appWithDict:(NSDictionary *)dict

{

return [[self alloc] initWithDict:dict];//返回MJApp对象的地址

}

@end

------------------------------------------

 

//0326应用管理模型使用:    MJViewController.m文件中

 

#import "MJViewController.h"

#import "MJApp.h"

 

@interface MJViewController ()

/** 存放应用信息 */

@property (nonatomic, strong) NSArray *apps;

@end

 

@implementation MJViewController

 

- (void)viewDidLoad

{

[super viewDidLoad];

// 设置图片

iconView.image = [UIImage imageNamed:appInfo.icon];

// 3.4.2.添加名字-------------------------------------

nameLabel.text = appInfo.name;//nameLabel.text加载的是字符串.

}

 

- (NSArray *)apps//---------------字典数组转化为模型的方法:+++++++**********++++++++**********

 

{

if (_apps == nil) {

// 初始化

 

// 1.获得plist的全路径

NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];

 

// 2.将路径中的plist文件加载成字典数组

NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];//创建的到底是字典还是你数组还是字典数组,是字典还是数组看Root处是字典还是数组;

 

 

// 3.将dictArray里面的所有字典转成模型对象,放到新的数组中

NSMutableArray *appArray = [NSMutableArray array];//创建一个可变数组;

for (NSDictionary *dict in dictArray) {//遍历字典数组

// 3.1.创建模型对象

//            MJApp *app = [[MJApp alloc] initWithDict:dict];

MJApp *app = [MJApp appWithDict:dict];

 

// 3.2.添加模型对象到前面定义的可变数组中

[appArray addObject:app];//字典数组-模型-可变数组中?只是借助模型(这个类中的)appWithDict将字典

//转化为模型,

}

 

// 4.赋值

_apps = appArray;

}

return _apps;

}

 

3.使用xib封装一个自定义view的步骤 // (下面的方法在代码中是如何实现的);

1> 新建一个继承UIView的自定义view,假设类名叫做(MJAppView)

//MJAppView.xib的文件;

2> 新建一个MJAppView.xib文件来描述MJAppView内部的结构

//里面加UILable,UIImageView,UIButton在一个xib局部界面中;

 

3> 修改UIView的类型为MJAppView真实类型

//UILabel *nameLabel = (UILabel *)[appView viewWithTag:20];即代码中的强制类型装换;

4> 将内部的子控件跟MJAppView进行属性连线

/

5> MJAppView提供一个模型属性

MJApp.h  MJApp.m 一个是模型的两个数据;

6> 重写模型属性的set方法,因为在set方法中可以拿到外界传递的模型数据

7> 把模型数据拆开,分别设置数据到对应的子控件中

8> 补充:提供一个创建MJAppView的类方法,将读取xib文件的代码屏蔽起来

@end

//代码加载xib的方法:

for (int index = 0; index<self.apps.count; index++) {//+++++++**********++++++++**********

NSBundle *bundle = [NSBundle mainBundle];

// 读取xib文件(会创建xib中的描述的所有对象,并且按顺序放到数组中返回)//+++++++**********++++++++**********

NSArray *objs = [bundle loadNibNamed:@"MJAppView(省略xib后缀)" owner:nil options:nil];//MJAppView=MJAppView.xib//+++++++**********++++++++**********

UIView *appView = [objs lastObject];//+++++++**********++++++++**********

 

// 3.2.添加view

[self.view addSubview:appView];

 

// 3.3.设置frame

int row = index / totalcolumns;

int col = index % totalcolumns;

// 计算x和y

CGFloat appX = marginX + col * (appW + marginX);

CGFloat appY = 30 + row * (appH + marginY);

appView.frame = CGRectMake(appX, appY, appW, appH);

 

// 3.4.设置数据

MJApp *app = self.apps[index];

// 3.4.1.图片

//        UIImageView *iconView = appView.subviews[0];

UIImageView *iconView = (UIImageView *)[appView viewWithTag:10];

父类强制转化为子类

 

iconView.image = [UIImage imageNamed:app.icon];//模型中的app.icon返回的是字符串型的,只是不会打印@" ";

2014-04-17 19:56:34.787 01-应用管理[30319:70b] app.icon = icon_00

2014-04-17 19:56:34.787 01-应用管理[30319:70b] app.name = 天天酷跑

// 3.4.2.名称

//        UILabel *nameLabel = appView.subviews[1];

UILabel *nameLabel = (UILabel *)[appView viewWithTag:20];//强制类型转换viewWithTag返回的是UIView型的,所以需要强转;

nameLabel.text = app.name;//字符串传给一个文本,文本text的属性方法返回的是一个NSString型的;

}

--------------------------------------------------------------------------------------------------------------

0326笔记整理

 

1.纯代码方式实现九宫格

* 一个格子一个格子添加

* 使用for循环添加

2.字典转模型

* 什么是模型

* 好处分析

* 将字典转换为模型

* 模型提供字典转模型的构造方法

3.使用xib文件

* 用来描述九宫格

* 用来描述中间的提示信息

4.封装

* 纯代码的封装

* xib的封装

 

//使用xib和模型完成九宫格的思路:

1>新建xib文件,添加局部空间,设置tag,方便以后使用;

2>

 

 

 

 

 

 

QQ好友列表设计思路:

1>获取plist数据必须有模型建模型,好友列表的模型是:plist=2个字典+friends数组(有n个字典,字典有:name,icon,intro,online属性);

1.1  friend模型:  *friends; online; NSString *name;

 

-(instancetype)initWithDict:(NSDictionary *)dict

{

if (self=[super init]) {

[self setValuesForKeysWithDictionary:dict];

}

return self;

}

 

1.2   friendGroup模型:name,icon,intro,online

-(instancetype)initWithDict:(NSDictionary *)dict//一次转化一个模型

{

if (self=[super  init])

{

//注入所有的属性   三个属性转化为字典

[self setValuesForKeysWithDictionary:dict];//此处的self打印还是数组和两个模型

//创建,遍历,转化,添加,赋值   处理特殊的属性

//下面的是补充转化,二次处理

NSMutableArray*models=[NSMutableArray arrayWithCapacity:self.friends.count];

//取出self.frends数组中的每个字典转化,没经历下面的遍历转化之前,frends数组中存的是N个字典,遍历后frends中

存放的是模型地址

for (NSDictionary*dict in self.friends) {

MJFriend*friend=[MJFriend  friendWithDict:dict];

[models addObject:friend];//medels是一个数组,转化后存放4个模型的数组

}

self.friends=models;//models        是模型数组,MJFriend中friend是转化后的模型数组:里面存放有很多单个模型

}//打印看下

//返回的是一组模型;

return self;//至此self打印是一个地址,彻底封装为一个模型;重新打印[self setValuesForKeysWithDictionary:dict],里面是10个模型地址;

}

 

2>都是:tableViewcell,是使用自定义的cell,所以必须要tableViewcell;

2.1里面拖UITableViewController,

2.2MJViewController : UITableViewController

2.3UITableViewController的类名为MJViewController ;

2.4里面有cell需要用到的数据:friend*

 

 

3>MJFriendCell类:   MJFriendCell 继承 UITableViewCell   //对应于管理XIB的文件

3.1方法cellWithTableView:根据tableView返回一个cell(创建出列,返回)

3.2MJFriend *对象,重写set方法为friend设置属性数据,每个好友的头像,签名,状态信息

 

 

 

4>MJHeaderView类:   MJHeaderView 继承 UITableViewHeaderFooterView

4.1专门用来添加头部视图:在头部视图中(contentView中)添加btn(包含imageView和settitle)和nameLabel就可以完成显示功能

4.2设置位置,情况,imageView的选装和防止变形

4.3 [self.btn addTarget:self action:@selector(headerClick) forControlEvents:UIControlEventTouchUpInside];

响应事件,并作相应的处理

-(void)headerClick  0428的代码最后一节课;

{

self.group.opened=!self.group.isOpen;

if ([self.delegate  respondsToSelector(返回BOOL):@selector(headerViewDidClick:)]) //判断方法headerViewDidClick:是否实现

[self.delegate headerViewDidClick:self];//如果实现就让headerView的代理  去调用headerViewDidClick这个方法,同时把自己传进出;

}

 

}

4.4headerViewDidClick中reload方法,在UITableView中,UITableView 继承 UIScrollView,如果在MJHeaderView类中是无法

调用reload方法的,所以通知:UITableView代办,通知=代理,

声明一个协议,协议中声明有方法,申明代理:

4.4.1//声明一个协议

@protocol  MJHeaderViewDelegate <NSObject>

4.4.2//协议中声明有方法

- (void) headerViewDidClick:(MJHeaderView*)headerView;

@end

@interface MJHeaderView : UITableViewHeaderFooterView

4.4.3//申明代理

@property(nonatomic,weak) id <MJHeaderViewDelegate> delegate;

4.4.4//代理建立关系

viewForHeaderInSection中header.delegate=self;

4.4.5//实现协议中的方法

5>控制器:设置数据源方法,和代理新方法

 

1>多少组用到数据源,设计字典转模型;

2>每组多少行涉及,单个模型,属性

3>设置cell的属性

3.1:创建cell需要一个独立的类,保存创建cell的方法,cellWithTableView,还有为cell设置具体详细信息

3.2获取模型数据

3.3利用获得的模型和属性,为cell赋值;

 

self.btn.imageView.transform=CGAffineTransformMakeRotation(M_PI_2);旋转

self.btn.imageView.transform=CGAffineTransformIdentity;恢复位置

btn.contentEdgeInsets=UIEdgeInsetsMake(0,20, 0, 0);        // 设置label和imageview之间的距离

// 设置lable和imageView之间的间距 btn.imageEdgeInsets

btn.titleEdgeInsets=UIEdgeInsetsMake(0, 20, 0, 0);

self.btn.imageView.contentMode=UIViewContentModeCenter;

//超出的部分不剪切

self.btn.imageView.clipsToBounds=NO;

#pragma mark-旋转功能

//当视图添加到别的视图就会被调用,

-(void)didMoveToSuperview

{

if (self.group.isOpen)

{

self.btn.imageView.transform=CGAffineTransformMakeRotation(M_PI_2);

}else

{

self.btn.imageView.transform=CGAffineTransformIdentity;

}

//当视图被修改的时候就会调用这个方法,一般在这个方法中布局子控件

- (void)layoutSubviews

{

#warning 一定要调用父类的方法

[super layoutSubviews];

//设置点击按钮的button的frame

self.btn.frame = CGRectMake(0, 0, 320, 44);

//设置nameLable的frame

CGFloat lableY = 0;

NSLog(@" = %@\n",NSStringFromCGRect(self.bounds));

CGFloat lableH = self.bounds.size.height;

CGFloat lableW = 50;

CGFloat lableX =self.bounds.size.width-lableW-10;

self.nameLable.frame=CGRectMake(lableX, lableY, lableW, lableH);

NSLog(@"layoutSubviews\n");

}

打开关闭分组

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

//取出对应组的模型

MJFriendGroup*group=self.groups[section];

//group 模型,frinds存放好友的模型,

// NSLog(@"numberOfRowsInSection = %d\n",group.friends.count);

//friends数组中朋友的个数

 

return group.isOpen==NO  ?  0  :  group.friends.count;

}

 

 

 

 

 

 

 

 

 

1>老师讲的以后都是重点

2>面试的代码需要手写,几乎没有上机的

3>80%问项目:

思路,难点,用到的知识,怎么解决问题的,难点如何克服的.

 

1.Xcode自带头文件的路径

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/

Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/Frameworks/UIKit.framework/Headers

 

2.修改了系统自带头文件后,Xcode会报错,需要清除缓存

解决方案:删掉下面文件夹的缓存即可(aplle是电脑的用户名)

/Users/aplle/资源库/Developer/Xcode/DerivedData

或者

/Users/aplle/Library/Developer/Xcode/DerivedData

 

 

 

使用字典容易写错

Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据

 

使用模型的好处

所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业

模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性

使用模型访问属性时,编译器会提供一系列的提示,提高编码效率

app.name = @"Jack”;

NSString *name = app.name;

的坏处

一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编译器不会有任何友善提示,需要手敲

dict[@"name"] = @"Jack";

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

手敲字符串key,key

 

 

字典转模型的过程最好封装在模型内部

 

模型应该提供一个可以传入字典参数的构造方法

 

 

- (instancetype)initWithDict:(NSDictionary *)dict;

+ (instancetype)xxxWithDict:(NSDictionary *)dict;

instancetype在类型表示上,跟id一样,可以表示任何对象类型

instancetype只能用在返回值类型上,不能像id一样用在参数类型上

instancetype比id多一个好处:编译器会检测instancetype的真实类型

 

 

 

Xib文件可以用来描述某一块局部的UI界面

Xib文件的加载

方法1

//存放到数组中,数组中又用很多元素;

NSArray *objs = [[NSBundle mainBundle] loadNibNamed:@"MJAppView" owner:nil options:nil];

这个方法会创建xib中的所有对象,并且将对象按顺序放到objs数组中

(如果xib如右图所示,那么objs数组中依次会有3个对象:1个UIView、1个UIButton、1个UISwitch)

 

方法2

bundle参数可以为nil,默认就是main bundle

UINib *nib = [UINib nibWithNibName:@"MJAppView" bundle:[NSBundle mainBundle]];

NSArray *objs = [nib instantiateWithOwner:nil options:nil];

 

在开发阶段,面向开发者的是xib文件; 当把应用装到手机上时,xib文件就会转为nib文件

 

要想随意调整xib中view的尺寸,首先要设置size为Freeform

xib文件就会转为nib文件

 

 

 

xib文件和storyboard 区别:

xib文件就会转为nib文件

1>共同点:

都用来描述软件界面

都用Interface Builder工具来编辑

2>不同点

Xib是轻量级的,用来描述局部的UI界面

Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系

 

如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部子控件的创建屏蔽起来,不让外界关心

 

外界可以传入对应的模型数据给view,view拿到模型数据后给内部的子控件设置对应的数据

 

常用方法?

1>

- (void)setTitle:(NSString *)title forState:(UIControlState)state;

设置按钮的文字

2>

- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state;

设置按钮的文字颜色

3>

- (void)setImage:(UIImage *)image forState:(UIControlState)state;

设置按钮内部的小图片

4>

- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;

设置按钮的背景图片

5>

设置按钮的文字字体(需要拿到按钮内部的label来设置)

btn.titleLabel.font = [UIFont systemFontOfSize:13];

6>

- (NSString *)titleForState:(UIControlState)state;

获得按钮的文字

7>

- (UIColor *)titleColorForState:(UIControlState)state;

获得按钮的文字颜色

8>

- (UIImage *)imageForState:(UIControlState)state;

获得按钮内部的小图片

9>

- (UIImage *)backgroundImageForState:(UIControlState)state;

获得按钮的背景图片

 

0418QQ图片错误;

Cannot find executable for CFBundle 0x8bbea80 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/AccessibilityBundles/CertUIFramework.axbundle> (not loaded)

 

 

对象都是类创建出来的;

 

 

 

 

 

15:08边走边转,覆盖

- (IBAction)move:(UIButton *)sender {

CGAffineTransform transform = self.headBtn.transform;

 

switch (sender.tag) {

case 1: // 上

transform = CGAffineTransformTranslate(transform, 0, -10);

break;

 

case 2: // 右

transform = CGAffineTransformTranslate(transform, 10, 0);

break;

 

case 3: // 下

transform = CGAffineTransformTranslate(transform, 0, 10);

break;

 

case 4: // 左

transform = CGAffineTransformTranslate(transform, -10, 0);

break;

}

 

self.headBtn.transform = transform;

}

 

- (IBAction)headClick {

self.headBtn.transform = CGAffineTransformIdentity;

}

 

- (IBAction)scale:(UIButton *)sender {

CGAffineTransform transform = self.headBtn.transform;

 

switch (sender.tag) {

case 5: // 放大

transform = CGAffineTransformScale(transform, 1.2, 1.2);

break;

 

case 6: // 缩小

transform = CGAffineTransformScale(transform, .8, .8);

break;

}

 

self.headBtn.transform = transform;

}

 

- (IBAction)rotate:(UIButton *)sender {

CGAffineTransform transform = self.headBtn.transform;

 

switch (sender.tag) {

case 7: // 左旋转

transform = CGAffineTransformRotate(transform, -M_PI_4);

break;

 

case 8: // 右旋转

transform = CGAffineTransformRotate(transform, M_PI_4);

break;

}

 

self.headBtn.transform = transform;

}

15:30旋转边走边转边转

命名规范.lable结尾

- (IBAction)move:(UIButton*)sender {//此处不能用id 用id无法实现

[UIView beginAnimations:nil context:nil];//必须一起使用

[UIView setAnimationDuration:3];//设置时间,没此行就是默认的时间

CGPoint  temp=self.iconBtn.center;

 

 

switch (sender.tag) {

case 10:

temp.y-=60;

break;

case 20:

temp.y+=60;

break;

case 30:

temp.x-=60;

break;

case 40:

temp.x+=60;

break;

}

 

self.iconBtn.center=temp;

[UIView commitAnimations];//提交动画;

}

 

bounds的使用:

- (IBAction)small {

//    1.取出原有属性

//    CGRect tempFrame = self.iconBtn.frame;

CGRect tempBounds = self.iconBtn.bounds;//和frame 的差不多

//    2.修改临时属性

tempBounds.size.width -= 50;

tempBounds.size.height -= 50;

//    3.覆盖原有属性

self.iconBtn.bounds = tempBounds;

}

center的使用;

 

- (IBAction)move:(UIButton *)sender {

 

 

//    1.取出原有属性

//    CGRect tempFrame = self.iconBtn.frame;

//    command + control + e

CGPoint tempCenter = self.iconBtn.center;

//    2.修改临时属性

//    偏移位

NSInteger offset = 150;

//    3.覆盖原有属性

//    self.iconBtn.frame = tempFrame;

self.iconBtn.center = tempCenter;

 

}

 

7.监听按钮点击

--------------------------------------------------------------------------------

代码创建界面

----------------------------------------

//  NJViewController.m

#import "NJViewController.h"

 

@interface NJViewController ()

 

@end

 

@implementation NJViewController

// 控制器的view加载完毕之后就会自动调用这个方法

- (void)viewDidLoad

{

[super viewDidLoad];

// 1.创建按钮

UIButton *btn = [[UIButton alloc] init];

//    3.设置按钮的frame

btn.frame = CGRectMake(100, 100, 100, 100);

btn.backgroundColor = [UIColor redColor];

//    4.设置背景图片

//    4.1创建图片(如果图片是png格式可以省略扩展名)

UIImage *image = [UIImage imageNamed:@"btn_01"];

//    4.2设置默认状态背景图片

[btn setBackgroundImage:image forState:UIControlStateNormal];

UIImage *imageHigh = [UIImage imageNamed:@"btn_02"];

[btn setBackgroundImage:imageHigh forState:UIControlStateHighlighted];

//    5.设置文字

[btn setTitle:@"摸我啊" forState:UIControlStateNormal];

[btn setTitle:@"摸你妹" forState:UIControlStateHighlighted];

//    6.设置文字颜色

[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];

[btn setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];

 

//    7.监听按钮点击

/*

addTarget: 哪个对象来监听事件就把这个添加给谁

action:事件发生后调用什么方法

forControlEvents:事件类型

 

sel中的方法,如果是监听的btn  就会将btn当做参数传进去

*/

此处是懒加载,

SEL sel = @selector(btnOnClick);

[btn addTarget:self action:sel forControlEvents:UIControlEventTouchUpInside];

 

//    2.添加按钮到view上

[self.view addSubview:btn];

 

 

//    创建添加按钮

//    创建系统提供类型的按钮不用设置位置和大小

UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeContactAdd];

//    添加到view

[self.view addSubview:btn2];

}

 

 

- (void)btnOnClick

{

NSLog(@"btnOnClick");

}

 

- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

 

@end

 

--------------------------------------------------------------------------------

 

 

 

 

 

 

//公共使用的常量提出来  设一个变量赋值;

 

 

self.previousBtn.enabled=(self.index=0 ? NO :YES);//不行

 

self.previousBtn.enabled=(0==self.index ? NO :YES);//不行

 

 

 

 

 

 

NSString*fileName=[NSString stringWithFormat:@"drink_%02d.jpg",i];

UIImage*image=[UIImage imageWithContentsOfFile:@"fileName"];无缓存储的

 

NSLog(@"%@ \n",fileName);

UIImage*image=[UIImage image:@"fileName"];有缓存   占用空间大;

 

 

 

 

 

覆盖,view里面的东西有讯息,,storyboard,里面有顺序,会覆盖.不可能把button加到UIimageView里面,

 

 

/**   */

//

#pragma

0419计划安排:

 

1.先看今天的代码整理下笔记,;

2.不懂的看下视屏幕,

3.重点代码敲一下,自己重复做老实讲的项目

4.看下昨天的代码:真理下笔记;

5.预习下后天,老后天上课的内容!

//==   =之间的使用:必须0==index?:no,yes     不要  index=0?no,yes

 

 

字典:保存数据, 通过键取

数据模型:保存数据

//         专门用来保存数据的对象称之为数据模型

//         数据模型就是继承NSObject的一个类

*/

 

 

4.1创建模型对象

/*

NJApp  *app = [[NJApp alloc] init];

app.name = dict[@"name"];

app.icon = dict[@"icon"];

*/

 

NJApp *app = [[NJApp alloc] initWithDict:dict];

 

应用管理封装自己敲中uiLABle  里还有UIview   objes中

应用管理封装2,李明杰:封装是怎么样的过程;

 

 

//桃木猫

#pragma mark - 喝奶点击事件

- (IBAction)drink {

/*

//    self.tomImageView.image = [UIImage imageNamed:@"drink_00.jpg"];

//    0判断是否正在执行动画

if ([self.tomImageView isAnimating]) {

return;

}

 

//    1.创建图片对象

//    1.1定义数组保存图片对象

NSMutableArray *images = [NSMutableArray array];

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

//    1.2获取图片名称

NSString *fileName = [NSString stringWithFormat:@"drink_%02d.jpg", i];

//        NSLog(@"%@", fileName);

//        1.3通过图片名称创建图片对象

UIImage *image = [UIImage imageNamed:fileName];

//        1.4添加图片对象到数组

[images addObject:image];

}

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

//    2.赋值图片数组给UIImageViwe

self.tomImageView.animationImages = images;

//    4.设置动画重复次数

self.tomImageView.animationRepeatCount = 1;

//    5.设置动画时间

self.tomImageView.animationDuration = images.count * 0.05;

//    3.启动动画4

[self.tomImageView startAnimating];

*/

[self runAnimationWithFileCount:80 andFileName:@"drink"];

}

- (IBAction)knock {

[self runAnimationWithFileCount:80 andFileName:@"knockout"];

 

}

 

- (IBAction)leftFoot:(id)sender {

 

[self runAnimationWithFileCount:29 andFileName:@"footLeft"];

}

 

#pragma mark - 播放动画

- (void)runAnimationWithFileCount:(NSInteger)count andFileName:(NSString *)name

{

//    0判断是否正在执行动画

if ([self.tomImageView isAnimating]) {

return;

}

 

//    1.创建图片对象

//    1.1定义数组保存图片对象

NSMutableArray *images = [NSMutableArray array];

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

//    1.2获取图片名称

NSString *fileName = [NSString stringWithFormat:@"%@_%02d.jpg", name, i];

//        NSLog(@"%@", fileName);

//        1.3通过图片名称创建图片对象

//        图片对象被覆盖后没有释放的原因:

//        imageNamed: 自动缓存

//        UIImage *image = [UIImage imageNamed:fileName];

//        imageWithContentsOfFile: 没有缓存

//        OfFile: 全路径

//        获取最主要的资源包

NSBundle *bundle = [NSBundle mainBundle];

//        获取图片的全路径

NSString *fullPath = [bundle pathForResource:fileName ofType:nil];

UIImage *image = [UIImage imageWithContentsOfFile:fullPath];

//        1.4添加图片对象到数组

[images addObject:image];

}

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

//    2.赋值图片数组给UIImageViwe

self.tomImageView.animationImages = images;

//    4.设置动画重复次数

self.tomImageView.animationRepeatCount = 1;

//    5.设置动画时间

//    动画持续时间

CGFloat delay = images.count * 0.05;

self.tomImageView.animationDuration = delay;

//    3.启动动画

[self.tomImageView startAnimating];

 

//    self.tomImageView.animationImages = nil;

 

/*

SEL: 要执行的方法

withObject:调用方法的时候传递的参数

afterDelay:多少秒后执行

谁调用performSelector方法就会在afterDelay秒后执行谁的SEL方法并且传递一个withObject参数

*/

三秒之后文件中的对象执行clearCache:方法,传递的参数为nil

//    [self performSelector:@selector(clearCache:) withObject:nil afterDelay:3];

//self.tomImageView这个属性  在延时之后执行setAnimationImages:这个方法,传递一个nil给他;

setAnimationImages:是系统自动生成的;

[self.tomImageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:delay + 1];

}

 

#pragma mark - 清空数组

- (void)clearCache:(NSString *)str

{

//    NSLog(@"clearCache = %@", str);

self.tomImageView.animationImages = nil;

 

//    [self.tomImageView setAnimationImages:nil];

}

@end

 

 

0418笔记

// 谁触发事件就会把谁当作参数传递过来

// 参数的作用:区分按钮

//- (IBAction)login:(UIButton *)sender {

//    NSLog(@"%@", sender);

//}

 

 

if (_imageData == nil) {

//        arrayWithContentsOfFile接收的不是文件名称,而是文件的全路径

//        abc.txt

//        /user/apple/desktop/abc.txt

//        OfFile:都是要求传入全路径

 

//        NSBundle : 代表一个文件夹

//        mainBundle: 程序的主要资源文件夹

//        /Users/apple/Library/Application Support/iPhone Simulator/7.1/Applications/5134E673-89EA-4D2B-AAC1-097594A7C8D9/06-图片浏览器.app

//        以后在开发中,创建plist文件一定不要命名为info.plist

NSBundle *bundle = [NSBundle mainBundle];

NSString *fullPath = [bundle pathForResource:@"imageData" ofType:@"plist"];

 

_imageData = [NSArray arrayWithContentsOfFile:fullPath];

}

 

 

//老师做传智猜图:如何构思的?如何思考的??

 

 

 

图片浏览器的思路??(100字 ):

1>设置属性,

2>监听按钮;

3>按钮被点击的时候:响应函数里  通过属性将相关的序号,图片,说明输出到,设置的属性里;

 

 

汤姆猫??:

1>监听按钮,设置UIView的属性,接受动画

2>设置数组,循环接受动画,使用for循环,

3>接受到的数组图片,使用系统的动画函数,播放动画;

 

九宫格思路:

??

猜图思路:

固定的用story,动态的用代码

 

@2x.png,.png同一张

view只是展示图片,效率高

button点击和展示;

 

 

 

修改工程名称;

inset设置内边距

disable just image

preferredStatusBarStyle 一敲就有继承的系统就有

枚举:枚举开头,

button不可用:enable=NO;

有dictionary  转化为模型

 

 

if (self=[super init])   首先调用[super init],调用父类的初始化方法,初始化以后,再返回一个

调用这个方法的对象的地址,赋值是为了return self,return [super init];验证,

MJQuestion*question=self.question[self.index];

 

 

btn下一题可以连线两次,属性和action   一个响应点击,一个获取这个按钮的属性;

cover.alpha=0.0;

设置透明:1.完全透明

 

 

self.view   代表控制器的view,  self.answerBtn.frame.Size

把控制view 的btn子视图带到控制器view最前面

[self.view bringSubviewToFront:self.iconBtn];

 

 

autolayout,勾选,btn控件就不能改变大小

autosize  subviews  勾选 子控件的大小随父控件的大小变化

 

两个连线

view

属性中不要用,用NSMutableArray避免外面修改

 

UI调用set方法一般的都是set开头,   调用get方法,直接敲

 

 

 

 

一个按钮可以拖多跟线,一个属性,一个响应;

 

 

 

cover.frame=self.view.frame;

 

 

建父控件的时候为什么是 view,view最纯洁什么都不干;也可以用其他的控件装子控件;

UITableView 继承UIScrollView,把一个东西拖到里面就可以滚;

 

 

 

 

viewDidLoad  程序启动就会

 

 

setv

字典转模型一行是四行;

属性名和 字典的key必须和模型的属性名一模一样;

取出每个字典的值赋值给属性名变量

id 类型是指针 不恩能是22;

 

@22  把22包装为指针;

 

@22   kvc会解析这个;

@"22"   会自动装换类型;

 

kvc字典转模型

取值   赋值

 

模型转字典

 

 

 

 

 

iPad   iPhone  名字不能错

 

forkeypath  属性 的属性,属性,赋值

setValue:只能给属性赋值;

forkey少用  用forkeypath

kvc的,装换,性能不是很高;

kvc通过字符串类型的键赋值,可能写错,编译时不会写错,运行的时候会报错;

 

kvo  键值监听

 

 

需要用self是用全局,的变量,   不需要用self 的是局部的变量;

重写构造方法:if(self=[superinit])

调用父类的构造方法,返回一个子类的对象;

 

 

 

 

view比较纯洁的view 可以容纳其他的控件;

 

imageView   放在scrollview的子控件可以拖:需要告诉滚动范围;代码才能实现滚动的范围;

不能滚动;

1>没设置滚动范围

2>scrollenabe=no;

3>imageView的自动布局要去掉,否则无法拖动

4>userInterfaction;

 

viewDidLoad代表方法已经加载程序启动

 

 

self.scrollView.contentInset=UIedgeInsetMake:  UIedgeInset是结构体在 设置的时候直接

把结构体的名称加一个make 就行;

 

scrollView

 

scrollinset:设置滚动的外边距;

inset在button中设置内边距;

 

 

图:

conetntSize的x值是相对与内容的内边距来算的,不是以inset的边距来算的;

 

 

CGrectMak

 

传智电台:

1>分三部分:上中下:

 

pt 点坐标:五个按钮:

 

 

scollview的协议以scollview为开头

 

 

 

 

14:45??三种设置滚动范围;

代理的应用场景:用途必背:

监听思想:A(viewController)对象想监听B对象,就将A(viewController)对象设为B对象的代理;

通知思想:A(viewController)对象想通知B对象,就将A(viewController)对象设为B对象的代理;

 

 

15:22代理大白话思想重看

 

 

分页原理:自动更具scrollView的宽度分页,需要设置参数;

 

nstimer只能放在主线程中,viewDidLoad中是主线程;

 

 

 

 

for (NSDictionary *dict in dictArray) {

NJQuestion *question = [NJQuestion questionWithDict:dict];

[models addObject:question];

}

遍历dictArray中的每个数组元素,再将每个元素转化为模型,将转化后的没个模型放在models中;

 

 

 

如果UIScrollView无法滚动,可能是以下原因:

1>没有设置contentSize

2>scrollEnabled = NO

3>没有接收到触摸事件:userInteractionEnabled = NO

4>没有取消autolayout功能(要想scrollView滚动,必须取消autolayout)

 

@property(nonatomic) CGPoint contentOffset;(.外面的所以off set 远离设置的范围)

这个属性用来表示UIScrollView滚动的位置

 

@property(nonatomic) CGSize contentSize;(size  )

这个属性用来表示UIScrollView内容的尺寸,滚动范围(能滚多远)

 

@property(nonatomic) UIEdgeInsets contentInset; (inset  设置外边距)

这个属性能够在UIScrollView的4周增加额外的滚动区域

 

@property(nonatomic) BOOL bounces;

设置UIScrollView是否需要弹簧效果

 

@property(nonatomic,getter=isScrollEnabled) BOOL scrollEnabled;

设置UIScrollView是否能滚动

 

@property(nonatomic) BOOL showsHorizontalScrollIndicator;

是否显示水平滚动条

 

@property(nonatomic) BOOL showsVerticalScrollIndicator;

是否显示垂直滚动条

 

开始拖拽时调用 :scrollViewWillBeginDragging

具体滚动到某个位置时,调用scrollViewDidScroll:方法   DidScroll已经滚到

 

用户停止拖拽时,

调用scrollViewDidEndDragging:willDecelerate:方法

 

设置UIScrollView的id<UISCrollViewDelegate> delegate代理对象

设置minimumZoomScale :缩小的最小比例

设置maximumZoomScale :放大的最大比例

让代理对象实现下面的方法,返回需要缩放的视图控件

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;

 

 

跟缩放相关的其他代理方法

开始缩放的时候调用

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view

 

正在缩放的时候调用

- (void)scrollViewDidZoom:(UIScrollView *)scrollView

只要将UIScrollView的pageEnabled属性设置为YES,UIScrollView会被分割成多个独立页面,里面的内容就能进行分页展示

 

一般会配合UIPageControl增强分页效果,UIPageControl常用属性如下

一共有多少页

@property(nonatomic) NSInteger numberOfPages;

 

当前显示的页码

@property(nonatomic) NSInteger currentPage;

 

只有一页时,是否需要隐藏页码指示器

@property(nonatomic) BOOL hidesForSinglePage;

 

其他页码指示器的颜色

@property(nonatomic,retain) UIColor *pageIndicatorTintColor;

 

当前页码指示器的颜色

@property(nonatomic,retain) UIColor *currentPageIndicatorTintColor;

 

 

NSTimer叫做“定时器”,它的作用如下

在指定的时间执行指定的任务

每隔一段时间执行指定的任务

 

调用下面的方法就会开启一个定时任务

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget

selector:(SEL)aSelector

userInfo:(id)userInfo

repeats:(BOOL)yesOrNo;

每隔ti秒,调用一次aTarget的aSelector方法,yesOrNo决定了是否重复执行这个任务

 

通过invalidate方法可以停止定时器的工作,一旦定时器被停止了,就不能再次执行任务。只能再创建一个新的定时器才能执行新的任务

- (void)invalidate;

 

注意点:字典中的key必须和模型的属性名称一模一样  才能使用KVC方法;

注意:不要滥用kvc

因为kvc要把字符串类型的属性名称和值转换后才能赋值,所以性能不是很高

还有一点,因为kvc是通过字符串类型的键去查找对应的属性进行赋值,所以有可能写错,但是写错后在编译时不会报错, 只会在运行时报错

应用场景:

常用于字典和模型的相互转换

*/

 

- (instancetype)initWithDict:(NSDictionary *)dict

{

if (self = [super init]) {

以前的字典转模型;

/*

self.answer = dict[@"answer"];

self.icon = dict[@"icon"];

self.title = dict[@"title"];

self.options = dict[@"options"];

*/

//        KVC可以通过一个字符串的key给属性赋值

//        取出dict字典中key为@"answer"的值 ,赋值给self的名字叫做answer的属性

/*

[self setValue:dict[@"answer"] forKeyPath:@"answer"];

[self setValue:dict[@"icon"] forKeyPath:@"icon"];

[self setValue:dict[@"title"] forKeyPath:@"title"];

[self setValue:dict[@"options"] forKeyPath:@"options"];

*/

//        注意点:字典中的key必须和模型的属性名称一模一样

使用KVC后一行代码搞定,KVC 自己会转化为响应的代码;

[self setValuesForKeysWithDictionary:dict];

 

[self setValue:dict[@"an"] forKeyPath:@"an"];

*/

}

return self;

}

 

 

KVC

// 可以给p对象的属性的属性赋值

[p setValue:@"mini" forKeyPath:@"iPad.model"];

// 只能给p对象的属性赋值

//    [p setValue:@"mini" forKey:@"iPad.model"];

 

    

    

 

 

 

 

[super viewDidLoad];

CGFloat lastY=self.lastBtn.frame.origin.y+self.lastBtn.frame.size.height+10;

//移动的距离

self.scrollView.contentSize= CGSizeMake   (0, lastY);

 

//移动上下的边缘

//离上下的间距,不会回缩.上下有工具条

self.scrollView.contentInset=UIEdgeInsetsMake(44, 0, 64, 0);

 

 

更改电台出来初始位置,下移;

//    1.取出原来的值

CGPoint tempOffset = self.scrollView.contentOffset;

//    2.修改以前的位置

/tempOffset.y = -40;

//    3.覆盖以前的offset

self.scrollView.contentOffset = tempOffset;

传智电台组成:

1>上面的view条320*45;

2>中间的scrollView 滑动

3>最下面的view条 320*60;

 

 

 

 

- (void)viewDidLoad

{

[super viewDidLoad];

 

// 设置滚动范围

self.scrollview.contentSize = self.imageView.image.size;

// 1.设置代理对象

self.scrollview.delegate = self;

//---------------------------------------------

UIScrollView中 声明了协议: @protocol UIScrollViewDelegate;

,UIScrollView的属性delegaet遵守UIScrollViewDelegate这个协议(如下所示);

@property(nonatomic,assign) id<UIScrollViewDelegate>delegate;

将控制器对象传给delegate,delegate和控制器对象指同一对象,在控制器中实现协议中的方法

,那么scrollview就可以使用控制器实现的方法完成一定的功能,UIScrollView的属性delegate

和控制器指向同一地址,控制器实现了,就相当于自己实现了一样,直接使用;

 

 

//---------------------------------------------

 

 

/*

代理应用场景:

1. 监听思想:当A对象想监听B对象的变化的时候,就可以让A对象成为B对象的代理

2. 通知思想:当B对象发生了变化的时候想通知A对象,就可以让A对象成为B对象的代理

*/

 

// 设置缩放的最小和最大比例

self.scrollview.minimumZoomScale = 0.2f;

self.scrollview.maximumZoomScale = 2.0f;

}

 

// 3.实现协议中的方法

// 开始缩放的时候调用, 要求返回scrollview中需要缩放的控件

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

{

NSLog(@"开始缩放");

return self.imageView;

}

 

缩放过程中调用

- (void)scrollViewDidZoom:(UIScrollView *)scrollView

//{

//    NSLog(@"正在缩放");

//}

 

 

/**

*  缩放结束时调用

*

*  @param scrollView 当前的scrollview

*  @param view       被缩放的view

*  @param scale      缩放的比例

*/

//- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale

//{

//    NSLog(@"缩放结束");

//    NSLog(@"view = %@, scale = %.1f", view, scale);

//}

 

 

 

UITableView需要一个数据源(dataSource)来显示数据

 

UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等

 

没有设置数据源的UITableView只是个空壳

 

凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源

 

 

调用数据源的下面方法得知一共有多少组数据

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

 

调用数据源的下面方法得知每一组有多少行数据

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

 

调用数据源的下面方法得知每一行显示什么内容

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

 

UITableView的每一行都是一个UITableViewCell,通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行

 

UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图

 

辅助指示视图的作用是显示一个表示动作的图标,可以通过设置UITableViewCell的accessoryType来显示,默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:

UITableViewCellAccessoryDisclosureIndicator

 

UITableViewCellAccessoryDetailDisclosureButton

 

UITableViewCellAccessoryCheckmark

 

还可以通过cell的accessoryView属性来自定义辅助指示视图(比如往右边放一个开关)

 

 

@protocol UITableViewDataSource<NSObject>

 

@required

2>每组多少行

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

 

3>每组每行显示什么内容

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

 

@optional

1>有多少组

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;              // Default is 1 if not implemented

4>设置头部标题

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;    // fixed font style. use custom view (UILabel) if you want something different

5>设置尾部标题

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;

 

// Editing

 

// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;

 

// Moving/reordering

 

// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

 

// Index

 

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;                                                    // return list of section titles to display in section index view (e.g. "ABCD...Z#")

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;  // tell table which section corresponds to section title/index (e.g. "B",1))

 

// Data manipulation - insert and delete support

 

// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;

 

// Data manipulation - reorder / moving support

 

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;

 

@end

 

 

 

 

禁止用户交互:使按钮不能点:

 

 

 

 

 

 

 

//英雄展示设计思路:

0>搭接面,拖属性,加plist文件

1>建模新,属性:name.icon,intro

2>模型初始化

3>重写get写函数将字典数组里的数据转化为模型

3.1>字典转模型函数:

3.2>两种方法

4>只有一组

5>有一共有多少行:

6>设置cell中的数据:

6.1>取模型数据

6.2>根据模型数据设置cell的值:

7>设置行高

 

//团购界面思路

1>界面搭建:添加一个tableView,plist文件,图片

 

2>建立xib文件:因为团购网站的样式一样  可以复用,而微博是不可以复用的

3>建立管理xib的类:为了保证封装性,不用viewWithtag的方式拿到xib中的子控件,建立管理xib的类,设置属性

并拖线来,管理xib中的属性;  Table  View Cell,xib,xib管理类三者的名字一样;

4> 为了加载plist文件建立模型

5>为了将控制器设置为代理需要拖线,将数据源和控制器拖线建立联系

 

6> 1) 设置每一行cell的高度,

2)隐藏状态栏,

3)数据的懒加载,加载plist

4)数据源方法

5)一共有多少行数据

6)每一行显示怎样的cell---创建cell  给cell传递模型

 

不能拖线,不能改名字,团购网站自己敲://是因为管理xib的类不是继承与xib中的默认类,没建立联系;

 

story归controller管

xib 归响应的类管,不一定添加到controller

 

 

 

lable.center=CGPointMake(160, 240);//位置center易算

lable.backgroundColor=[UIColor  redColor];

[self.superview   addSubview:lable];  /找父控件

 

 

 

09:41主图层??

lable.layer.masksToBounds=YES;//子头层是否剪切到母涂层的大小,边缘一致;

0943

 

??什么意思?0945

lable.layer.cornerRadius=10;//两个配合使用

lable.layer.masksToBounds=YES;//设置子图层的边角,剪边角,边角变圆

lable.clipsToBounds=YES;

代码里面父子关系不稳定

 

custom  的下面修改xib名字的tg,xib的名字不能改,继承关系错了

 

 

 

 

展示表格使用tableView,要展示数据需要数据源;遵守数据源协议

数据源方法什么事后调用?  数据源显示之前调用

1204两种设置行高的方法;row.height,相同的行高设置的方法,不同的行高

static   局部变量只开辟一次存储空间

 

 

xib封装的读取与赋值的过程:-------------------------------1)xib转化为appview 类

1>调用appView方法从xib中加载局部界面

NJAppView *appView = [NJAppView appView];

appView.delegate = self;//        设置控制器为appview的代理

+ (instancetype)appView

{

//        获取最主要的资源文件夹

NSBundle *bundle = [NSBundle mainBundle];

//        nib == xib

//        读取xib中的文件(会创建xib中描述的所有对象,并且按照顺序放到数组中)

NSArray *objcts = [bundle loadNibNamed:@"NJAppView" owner:nil options:nil];

 

//        UIView *appView = objcts[0];

NJAppView *appView = [objcts lastObject];

// NJAppView  xib中是什么类型,objcts就是什么类型

return appView;//NJAppView继承UIView

}

 

 

2>.设置数据:.apps方法将字典中的字典转化模型放在数组中存储起来, --------2)取出每一个模型数据

//取出模型数组中的每一个模型数据:

NJApp *appInfo = self.apps[i];

- (NSArray *)apps

{

if (_apps == nil) { // 未初始化

//        1.获取最主要资源包

NSBundle *bundle = [NSBundle mainBundle];

//        2.获取plist全路径

NSString *fullPath = [bundle pathForResource:@"app" ofType:@"plist"];

//        3.加载应用信息

NSArray *dictArray = [NSArray arrayWithContentsOfFile:fullPath];

//        4.字典转模型

NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count];

 

for (NSDictionary *dict in dictArray) {

//            4.1创建模型对象

NJApp *app = [NJApp appWithDict:dict];

 

//            4.2将模型对象存储到数组中

[models addObject:app];

}

_apps = models;

}

return _apps;

}

 

3>.appInfo的get方法将 上一步中取得的模型数据,赋给xib中的nameLable和iconImageView中的模块

appView.appInfo = appInfo;-------------------3)将模型数据赋给appview 类的属性

 

- (void)setAppInfo:(NJApp *)appInfo

{

//    固定写法

_appInfo = appInfo;

 

//    设置头像

self.iconImageView.image = [UIImage imageNamed:_appInfo.icon];

//    设置名称

self.nameLabel.text = _appInfo.name;

}

 

 

//方法在NJappVIew中只有NJAppView的对象才能调用

- (IBAction)downloadClick {

//    NSLog(@"点击了下载");

self.download.enabled = NO;

//  self代表NJAppView,通知代理我被点击了,同时把NJAppView传给控制器是

[self.delegate appViewClickBtn:self];

}

 

 

1>xib中的一个按钮被点击了;

2>xib中被点击的按钮(downLaod)进行连线,只有连线了才可以监听这个按钮;

3>被点击的事件,xib的管理类MJAPPView最清楚自己的子控件被点击,保证封装,将点击事件通知代理:

通知控制器,

4>控制器收到被点击的事件后,在控制器上加弹框:

 

 

 

 

 

 

[self.view addSubview:label];

执行动画:透明从0.0--0.6花一秒钟的时间,经过0.5秒后,动画消失,消失时间持续1秒钟;

[UIView animateWithDuration:1 animations:^{

label.alpha = 0.6;

} completion:^(BOOL finished) {

 

[UIView animateWithDuration:1 delay:0.5 options:UIViewAnimationOptionCurveLinear animations:^{

label.alpha = 0.0;

} completion:^(BOOL finished) {

[label removeFromSuperview];

}];

 

}];

 

 

@interface MJTgCell : UITableViewCell//要继承系统的UITableViewCell做一个扩展;

xib转换为代码:

自定义的相当于MJTgCell这个类;

 

 

开发中字符串展示int  方便显示;

 

当系统的cell无法满足需求的时候,就需要自定义cell,在系统自带的cell上做一些增强;

自定义cell

1>xib固定的界面

2>纯代码(界面不固定,微博)

 

tableview  cell  子空间contentView(必须放在这里面),专门tableview  cell

 

 

 

 

 

 

定义一个类管理一个xib文件

1>xib与管理类名称相同

2>管理类是xib的class类的根类:

 

 

继承:在继承的基础上既要满足要求,又要扩张一些功能,所以我要继承与他,

 

 

 

hidden   成对出现,30分钟:

 

团购网站思路:

1>数据懒加载

2>设置行高,设置状态栏

3>每一行显示怎么样的cell:

调用:

创建cell,在创建的时候没传入一个tableView对象就返回一个cell

创建cell,先从缓存池中出,不为空创建.

4>给cell传模型数据

get 方法懒加载,获得模型数组,set方法将传入的模型,写入cell的各个属性;

5>

 

 

 

 

 

 

+ (instancetype)headerView

{

return [[[NSBundle mainBundle] loadNibNamed:@"NJHeaderView" owner:nil options:nil] lastObject];

}

// 通过xib创建的view不会调用这个方法,只有通过代码创建的时候才会调用这个方法

//- (id)init{}

 

// 通过xib创建view的时候会调用下列方法

- (void)awakeFromNib

{

NSLog(@"醒了");

//    拿到scrollview设置图片

}

 

 

控件的命名规则?

// 控件协议名称以控件名称 + Delegate

@protocol NJFooterViewDelegate <NSObject>

 

 

对象A内部发生了一些事情,想通知对象B

对象B想监听对象A内部发生了什么事情

对象A想在自己的方法内部调用对象B的某个方法,并且对象A不能对对象B有耦合依赖

对象A想传递数据给对象B

以上情况,结果都一样:对象B是对象A的代理(delegate)

 

 

先搞清楚谁是谁的代理(delegate)

 

定义代理协议,协议名称的命名规范:控件类名 + Delegate

定义代理方法

代理方法一般都定义为@optional

代理方法名都以控件名开头

代理方法至少有1个参数,将控件本身传递出去

设置代理(delegate)对象  (比如myView.delegate = xxxx;)

代理对象遵守协议

代理对象实现协议里面该实现的方法

在恰当的时刻调用代理对象(delegate)的代理方法,通知代理发生了什么事情

(在调用之前判断代理是否实现了该代理方法)

 

 

 

 

 

好友列表和微博思路:0425

 

1>viewDidLoad

2>prefersStatusBarHidden

A>//懒加载plist-数组-(字典转message模型,message模型set进入messageFrame模型,messageFrame模型组合成数组)

3> 数据源方法 ,使用懒加载返回frame模型的个数;决定行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return self.messageFrames.count;

}

 

4>-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

// 1.创建cell,传入tableview就可以将子控件创建和初始化;

MJMessageCell *cell = [MJMessageCell cellWithTableView:tableView];

 

// 2.使用懒加载get方法给创建和初始化的cell传递模型

//根据传入的模型设置:时间,头像和正文,以及frame属性  在cell使用setMessageFrame方法中设置,无返回值

cell.messageFrame = self.messageFrames[indexPath.row];

 

// 3.返回设置号头像和正文时间的cell

return cell;

}

 

5>- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{   //调用懒加载的方法给frame模型对象传递单个messageFrames模型

MJMessageFrame *mf = self.messageFrames[indexPath.row];

//根据传入的模型数据,get获得MJMessageFrame对象中set的cellHeight属性;此属性在色调方法中根据字数来设定;

return mf.cellHeight;

}

@end

 

 

0427:qq聊天布局的结构:

 

storyBorad:tableView  和文本输入框背景图片,三个按钮

 

QQ好友事项方法:

一:

定义分类(两组,扩充两个方法):

分类是在已有类的基础上扩展一些新的类,增加了获得可以随意拉伸不变形的图片

返回:可以随意拉伸不变形的图片,返回字符串所占用的尺寸

定义方法:

@interface NSString (Extension)

- (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize;

@end

 

定义: MJMessageCell类   继承自UITableViewCell

方法:

cellWithTableView   cell的创建<缓存池>

initWithStyle:      对创建的cell初步初始化:设下图像正文的格式,字体,里面无准确的内容

setMessageFrame:     传入一个MessageFrame,MessageFrame中有message属性,通过get

message属性的方法获得message的模型(无frame)

 

MJMessage类中

属性:聊天内容

发送时间

信息的类型

是否隐藏时间

 

方法:传入字典就可以返回一个模型

messageWithDict:(NSDictionary *)dict

- (instancetype)initWithDict:(NSDictionary *)dict

 

MJMessageFrame类中

属性:头像的frame,时间的frame,正文的frame ,cell的高度,单个初级数据模型message

方法:- (void)setMessage:(MJMessage *)message

传入message(单个模型数据)可以计算:

1.时间  _timeF

2.头像  _iconF

3.正文  _textF

4.cell的高度   cellheight

 

 

 

控制器中有@interface MJViewController () <UITableViewDataSource, UITableViewDelegate, UITableViewDelegate, UITextFieldDelegate>

数据源方法和代理;

 

属性: ;NSDictionary *autoreply;  NSMutableArray *messageFrames;

UITableView *tableView;  拖线-设置代理,通知代理做事

UITextField *inputView;  拖线-设置代理,通知代理做事

 

viewDidLoad:

1.表格的设置

去除分割线

2.监听键盘的通知

3.设置文本框左边显示的view

永远显示

懒加载:获得模型数据,将模型数据和数据的frame(内部新增加一些属性,在setMessage中设置)包装成:messageFrames,

数据源方法:1>创建,初始化,填数据,返回cellHeight;

autoreply:自动播放方法,返回的数组(plist转化而来);

发送一条消息:

- (void)addMessage:(NSString *)text发送的文本 type:(MJMessageType)type(发送的类型);

1.数据模型

设置数据模型的时间

看是否需要隐藏时间

2.frame模型

创建mf对象

MJMessageFrame *mf = [[MJMessageFrame alloc] init];

//对象中添加单个模型数据

mf.message = msg;

//含有单个模型数据和相关扩充功能的mf对象加到数组中;

[self.messageFrames addObject:mf];

// 3.刷新表格

[self.tableView reloadData];

// 4.自动滚动表格到最后一行

 

*  根据自己发的内容取得自动回复的内容

自己发的内容

- (NSString *)replayWithText:(NSString *)text

 

 

#pragma mark - 文本框代理

/**

*  点击了return按钮(键盘最右下角的按钮)就会调用

*/

- (BOOL)textFieldShouldReturn:(UITextField *)textField

{

// 1.自己发一条消息

// 2.自动回复一条消息

// 3.清空文字

// 返回YES即可

}

/**

*  当键盘改变了frame(位置和尺寸)的时候调用

*/

- (void)keyboardWillChangeFrame:(NSNotification *)note

{    // 设置窗口的颜色

// 0.取出键盘动画的时间

// 1.取得键盘最后的frame

// 2.计算控制器的view需要平移的距离

// 3.执行动画

}];

}

 

 

 

控制器中的新方法代码:

 

 

- (void)viewDidLoad

{

[super viewDidLoad];

// 1.表格的设置

// 去除分割线

self.tableView.backgroundColor = [UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1.0];

self.tableView.allowsSelection = NO; // 不允许选中

self.tableView.delegate = self;

 

// 2.监听键盘的通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

 

// 3.设置文本框左边显示的view

self.inputView.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 0)];

// 永远显示

self.inputView.leftViewMode = UITextFieldViewModeAlways;

self.inputView.delegate = self;

}

 

作用:

- (void)dealloc

{

[[NSNotificationCenter defaultCenter] removeObserver:self];

}

 

数据源方法:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

// 退出键盘

[self.view endEditing:YES];

}

 

>-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath//创建cell初步初始化--

代理方法:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

MJMessageFrame *mf = self.messageFrames[indexPath.row];

return mf.cellHeight;

 

 

 

}

 

/**

*  当开始拖拽表格的时候就会调用

*/

 

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

 

// 退出键盘

 

- (void)addMessage:(NSString *)text type:(MJMessageType)type

 

// 1.数据模型

MJMessage *msg = [[MJMessage alloc] init];

msg.type = type;

msg.text = text;

// 设置数据模型的时间

NSDate *now = [NSDate date];

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

fmt.dateFormat = @"HH:mm";

// NSDate  --->  NSString

// NSString ---> NSDate

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

//  2014-08-09 15:45:56

// 09/08/2014  15:45:56

msg.time = [fmt stringFromDate:now];

 

// 看是否需要隐藏时间

MJMessageFrame *lastMf = [self.messageFrames lastObject];

MJMessage *lastMsg = lastMf.message;

msg.hideTime = [msg.time isEqualToString:lastMsg.time];

 

 

 

 

_messageFrame = messageFrame;

//取得message模型

MJMessage *message =self.messageFrame.message;

self.messageFrame=也是右边传过来的:(上层代码)

 

 

 

 

 

 

 

 

0427:QQ列表

如何改textField 的圆角

答:label.alpha = 0.0;

//    label 图层(主图层)

label.layer.cornerRadius = 10;

//    设置超出主图层的子图层的边界自动剪切掉

label.clipsToBounds = YES;

 

09:23注意点;

2>系统自带的cell特点?

默认的状态:一个图像,一个button.

有的状态:有lable, imageView,button

 

 

 

 

1> 搭接面运行;

2>一进来3.5村,

3>字典转模型

4>数据源方法:

保存数据的模型不需要继承;

09:36枚举的命名规范

1>懒加载

2>初步创建cell,初步初始化;

 

 

09:08不能用tableViewController?

如果直接使用tableViewController,自动连好了tableView的数据源和代理;

在QQ列表之类的:里面上半部分是tableView,下面是Button,所以不能用TableViewer;

 

下面需要加view保存按钮(三个图片按钮)

 

09:11技巧,修改坐标的技巧,自己领悟;

09:12(添加到xcode图片的地方)ios7的图片不出来,修改jason文档,在四个的里面添加名字;fileName

 

在storyBoard中,imageView不能在上面放控件;代码中可以创建图像上面添加控件;

imageView继承UIview可以添加控件

 

@2X的时候像素是68*68,在Xcode里面真实的是34*34(xcode);button里的图片:如果添加到image中

图片不会拉升,添加到background中,图片会拉伸;

 

 

0952若应用,用强引用引用着他

 

1>获取屏幕的宽度:

1041计算屏幕的最大宽度和高度?

 

去掉分割线:两种:seperate添加函数:

tableview上放有cell,tableView上放有很多cell;

让tableView的某一行不能选?

在tableView的storyBoard的selction(无法选,单选,多选);

 

让button里面的数据显示多行,改storyBoard,;改按钮的圆角:在button的borderstyle里面

biatton里有image和lable

 

如何设置button内边距?  conetnInset

如何自动换行?numberoflines=0

拉伸函数?

 

ios五如何解决平铺;

拉伸的方法:

先放一个Button,Button里面有一个lable,lable里面放置 有文字,Button的背景加一个图片让图片的某一点拉升,拉伸函数有几种;

 

 

通知:发布者:名称接受者

 

 

15:46nil接受通知,代表谁都可以接受;监听通知,通知消失后,注册监听后,对象消失后,一定销毁监听;

 

note.info的作用?

可以打印出键盘的信息

NSLog(@"notoinfo = %@\n",note.info);

 

如何改键盘的return为send?

在storyBoard里面的修改returnKey,变为send

 

对于崩的程序,如何确定在哪里崩了?

 

// 2.frame模型

//创建mf对象

MJMessageFrame *mf = [[MJMessageFrame alloc] init];

//对象中添加单个模型数据

mf.message = msg;

//含有单个模型数据和相关扩充功能的mf对象加到数组中;

[self.messageFrames addObject:mf];

 

// 3.刷新表格

[self.tableView reloadData];

 

// 4.自动滚动表格到最后一行

NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];

[self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

- (void)setMessageFrame:(MJMessageFrame *)messageFrame(右边传过来的)

 

 

单例模式:

在内存中只分配一次存储空间:很多对象可以一应用他;

 

 

readOnly  在一个.h文件中声明为只读(只有get方法,没有set方法)的在他的.m文件中是可以通过直接赋值的,不能使用set方法赋值.

 

如何设置:

条件断点:循环中让断点停在某个地方;处于某个特定的状态停止;

断点忽略-在断点处  edit breakpoint;

点击控制台:print description;

异常断点:在断点异常的左下角中,点+,选择:Symbolic Breakpont :在Symbol中输入:objc_exception_throw

po 对象不存在时打印为nil;

 

print打印基本的数据类型;

info symbol 0xffdd;

调试的时候:某一点有问题,查找某一点有关的所有代码,一个个的检查;

 

放在message.m中:

/**

*  根据文本计算文本占用的宽高

*

*  @param str     要计算的文本

*  @param font    文本的字体和大小

*  @param maxSize 文本最大能占用的宽高

*/

CGSize textSize = [self sizeWithString:message.text font:NJTextFont maxSize:maxSize];  self代表messageFrame的对象;通过self调用;

//传入一个字符串,用一个对象调用

- (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize

{

NSDictionary *dict = @{NSFontAttributeName : font};

CGRect rect =  [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];

return rect.size;

}

/**

*  根据文本计算文本占用的宽高

*

*  @param str     要计算的文本

*  @param font    文本的字体和大小

*  @param maxSize 文本最大能占用的宽高

*/直接使用message.text调用;

CGSize textSize = [message.text sizeWithFont:NJTextFont maxSize:maxSize];

- (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize

{

NSDictionary *dict = @{NSFontAttributeName : font};

CGRect rect =  [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];

return rect.size;

}

 

#pragma mark - 转换拉伸图片方法:留出1*1的空间被拉,也可以直接(h,w,h,w)留0.000001;

+ (UIImage *)resizableImage:(NSString *)name

{

// 创建一张图片

UIImage *image =  [self imageNamed:name];

// 制作指定范围可以拉伸的图片

CGFloat w =  image.size.width * 0.5;

CGFloat h = image.size.height * 0.5;

UIImage *resizeImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(h - 1, w - 1, h, w) resizingMode:UIImageResizingModeStretch];

return resizeImage;

}

 

 

根据文字宽高的计算公式计算出文字的size,size的宽高属性加上间距就可以得出button的宽高,也就是计算出文字的frame,

设置的背景和button是一起的,内部的文字和button有间距,button 的frame是根据文字的size来设置的;

:

button上有文字:设置button的宽高,在设置button内部,文字的

// 3.正文frame

CGFloat contentY = iconY;

// 计算文本宽高,宽度150;

CGSize maxSize = CGSizeMake(150, MAXFLOAT);

// 文本实际占用的宽高

//    CGSize textSize = [self sizeWithString:message.text font:NJTextFont maxSize:maxSize];

CGSize textSize = [message.text sizeWithFont:NJTextFont maxSize:maxSize];

// 计算button的宽高

CGFloat contentW = textSize.width + NJEdgeInset * 2;

CGFloat contentH = textSize.height + NJEdgeInset * 2;

CGFloat contentX = 0;

if (NJMessageTypMe == message.type) {// 自己发

contentX = iconX - padding - contentW;

}else

{

contentX = CGRectGetMaxX(_iconF) + padding;

}

_contentF = CGRectMake(contentX, contentY, contentW, contentH);

 

 

- (void)setMessageFrame:(NJMessageFrame *)messageFrame

{

 

_messageFrame = messageFrame;

//    [self settingData];

//    [self settingFrame];

NJMessage *message = self.messageFrame.message;

 

// 1.设置时间

self.timeView.text = message.time;

self.timeView.frame = messageFrame.timeF;

 

// 2.设置头像

// 根据发送类型获取头像图片的名称

NSString *iconName = (NJMessageTypMe == message.type ? @"me" : @"other");

self.iconView.image = [UIImage imageNamed:iconName];

self.iconView.frame = messageFrame.iconF;

 

// 3.设置textView(即button)设置文字;

[self.textView setTitle:message.text forState:UIControlStateNormal];

//给textView设置frame,get和set方法

self.textView.frame = messageFrame.contentF;

 

// 设置背景图片

if (NJMessageTypMe == message.type) { // 自己发 蓝色

// 普通图片

 

//利用已封装好的方法给button设置一个只有中间1*1的地方可以拉伸的头像;

[self.textView setBackgroundImage:[UIImage resizableImage:@"chat_send_nor"] forState:UIControlStateNormal];

// 高亮图片

 

}else

{

// 白色图片

[self.textView setBackgroundImage:[UIImage resizableImage:@"chat_recive_nor"] forState:UIControlStateNormal];

}

 

- (BOOL)textFieldShouldReturn:(UITextField *)textField

{

//    NSLog(@"send按钮被点击了 %@",textField.text);

 

//    1.添加模型数据

 

//    1.1创建数据模型

NJMessage*ms=[[NJMessage alloc]init];

ms.text=textField.text;

//    1.2根据数据模型创建frame模型

NJMessageFrame*mf=[[NJMessageFrame alloc]init];

 

 

//    1.3将frame模型添加到messageFrames中

mf.message=ms;

//   [NJMessageFrame

//    2.刷新表格

[self.tableView reloadData];

 

return YES;

}

- (void)keyboardWillChange:(NSNotification *)note

{

//    NSLog(@"键盘弹出了");

//    让输入框随着键盘移动就OK

//    NSLog(@"%@", note.userInfo);

 

//    1. 取出键盘移动结束后的Y值

CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

// 键盘弹出后的Y值

CGFloat keyboardY  = rect.origin.y;

// 键盘的高度( 输入框要移动的距离)

CGFloat transformY = keyboardY - self.view.frame.size.height;

//    NSLog(@"%.1f", transformY);

 

//    2.取出键盘弹出需要的时间

CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

 

//    3.修改输入框位置

[UIView animateWithDuration:duration animations:^{

self.inputView.transform = CGAffineTransformMakeTranslation(0, transformY);

}];

}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

//    NSLog(@"被拖拽了");

[self.view endEditing:YES];

}

 

{

[super viewDidLoad];

// 设置tableView的背景颜色

self.tableView.backgroundColor = [UIColor lightTextColor];

// 设置tableview不能选中

self.tableView.allowsSelection = NO;

// 注册监听键盘位置改变的通知

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

//注册通知的监听器,有UIKeyboardWillChangeFrameNotification事件时时,self是监听器

 

通知中心(NSNotificationCenter)提供了方法来注册一个监听通知的监听器(Observer)

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;

/*observer:监听器,即谁要接收这个通知-----self

aSelector:收到通知后,回调监听器的这个方法,并且把通知对象当做参数传入keyboardWillChange:

aName:通知的名称。如果为nil,那么无论通知的名称是什么,监听器都能收到这个通知

anObject:通知发布者。如果为anObject和aName都为nil,监听器都收到所有的通知*/

[center addObserver:self(监听器) selector:@selector(keyboardWillChange:(回调的方法)) name:UIKeyboardWillChangeFrameNotification(通知的名称) object:nil(nil代表监听器可以收到所有的对象)];//

/*self  控制器对象*/

// 监听文本输入框召唤出来的键盘的发送按钮的点击

// 设置文本输入框代理

上述方法是键盘的,下面

self.inputTextField.delegate = self;设置代理做下面的事情;scroolView滚动时调用,滚动时让键盘结束编辑;

 

/* - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

//    NSLog(@"被拖拽了");

[self.view endEditing:YES];

}*/

}

#pragma mark - 键盘位置发生改变时调用

- (void)keyboardWillChange:(NSNotification *)note

{

//    NSLog(@"键盘弹出了");

//    让输入框随着键盘移动就OK

//    NSLog(@"%@", note.userInfo);

 

//    1. 取出键盘移动结束后的Y值

CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

// 键盘弹出后的Y值

CGFloat keyboardY  = rect.origin.y;

// 键盘的高度( 输入框要移动的距离)

CGFloat transformY = keyboardY - self.view.frame.size.height;

//    NSLog(@"%.1f", transformY);

 

//    2.取出键盘弹出需要的时间

CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];

 

//    3.修改输入框位置

[UIView animateWithDuration:duration animations:^{

self.inputView.transform = CGAffineTransformMakeTranslation(0, transformY);

}];

}

 

 

 

某个控件出不来:

1.frame的尺寸和位置对不对

2.已经出来了,没显示正确的内容,赋值出错,误以为没出来;

2.hidden是否为YES

3.有没有添加到父控件中

4.alpha 是否 < 0.01

5.被其他控件挡住了

6.父控件的前面5个情况

 

但凡init创建的控件frame都是0;1448?必须在layOutSubviews中设置frame,init里面不能设置frame;

layOutSubviews,一定要记住;

frame修改了会调用:-(void)layOutSubviews

 

 

.m文件中声明的弱引用的属性

@property (nonatomic, weak) UIImageView *iconView;

{

//在此处不能:self.timeView=[UILable alloc ]init]  self.timeView中的timeView属性是weak的即若应用,在创建的

后就会释放,使用新创建的默认是强引用;

UILabel *timeView = [[UILabel alloc] init];

timeView.textAlignment = NSTextAlignmentCenter;

timeView.font = [UIFont systemFontOfSize:13];

[self.contentView addSubview:timeView];

self.timeView = timeView;//右边的timeView是强指针,左边的是弱指针,相当于有两个指针指着timeView,那么timeView就不会消失

}

 

 

0428:QQ好友列表;

老师的面试题?

如何解决移动(键盘和输入条)不一致:动作不一致;

使控制器(包含tableView和输入buttton)参见0427代码整体移动;

widow 继承UiView window子控件是控制器view

Nslog(@"%@",self.view.superView)打印父控件;

如何解决黑色?

更改UIWindow的颜色,使UIwindow的颜色和view的背景颜色一致;

0923代码运行-第一份代码;

差别:键盘输入框调出,有输入框管理;

添加数据:改懒加载de NSArray 为NSMutableArray;

 

如何操作tableView滚到最后一条?

- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)(此处是枚举可以进去看下什么)scrollPosition animated:(BOOL)animated;滚到哪一行,在UITableView

 

发送完如何清空输入框?:

self.inputView.text=nil;

 

改输入框线的位置:

leftView,(添加一次:在viewdeload);

更改显示模式leftViewMode的模式:代码?

 

如何获取当前时间:NSDate;

NSDate*date=[NSDate date];//返回当前时间;

NSLog(@"date = %@\n",date+8);//东华区,

 

时间转字符串;如何输出时间代码(1节)

NSDateFormatter*fm=[NSDateFormatter alloc]init];

fm stringf

时间格式:

 

判断是否需要时间:

取出上一条,-数组的最后一条消息;

判断时间是否相等

 

 

 

静态单元格;

 

如果运行结果与预期不一样

有缓存:

删模拟器软件,再clean;

 

tableViewController添加步骤?(xib类似)

1>NJViewController 继承与UItableVIewcontroller,

2>删掉strory的controllerViewor 重新拖一个UItableVIewcontroller,

3>更改UItableVIewcontroller的class名位NJViewController

 

tableViewController加,改继承,改类;

tableViewController已经实现了代理数据源方法不用拖线

 

 

改group就是分组;

 

修改模式:tableVIew-static

把cell设置为静态的;

 

设置静态设置成怎么样就是怎么样的;

 

stattic-cell(basic  stytle)--设置image

下一级设置lable;

tableView group分组,设置组数(界面中);

静态单元格用在设置等不变的地方;可以在界面中修改行高;

0>创建tableViewController   (步骤);

1>好友列表

2>创建两个模型:MJFRiendGroup;mjFrend

属性:frends,name ,online

mjFrend属性:四个属性;(pilst文件决定)

 

3>字典转模型

两个方法传字典返回模型;

//注册所有的属性,frends中存放的还是字典;

对frends数组进行转换;

 

mjFrend中提供两个方法将字典转换为模型

 

kvc转换的是字典,需要将字典转模型

 

全部是tableView  拖一个tableView;

 

4>实现数据源方法:

4.1>多少组;

4.2>每一组有多少数据;numberof

4.2.1.取出对应租的模型

4.2.2.返回当前组中有多少好友;

4.2.3.只写一句,再把cell打上标记@ abc,自动创建

4.2.3.1  创建模型,取出对应组的组模型;

4.2.3.2  取出组对应行的模型

4.2.3.3用对应租的模型为cell赋值;

 

 

 

14:08打印bounds?

UITableView

5>去处状态栏

//6>头部标题,取得对应组的模型

 

怎么找方法?分组的标题上放按钮;

1>显示分组,调用数据源的方法,由于在头部标题中需要可以点的view,有一个返回nsStringd的类似的方法,不对;

2>由于需要视图是UIView的再到代理中找是否有返回UIView,名称类似的方法;

 

 

6>添加头部视图view(解决性能)

下面的封装,继承与tableViewcell的类;

1.headerView中添加按钮

创建添加到contentView

2.添加lable

创建添加lable

return cell

3.设置数据;

UIButton里面有添加加好按钮的方法:buttonwith...

 

设置分组的头部视图数据;

一个视图不显示:

 

NSLog(@"<#name#> = %@\n",NSStringFromCGrect);

 

QQ好友列表

 

 

 

对齐方式:

1>content内容对其方式;左对齐?代码 contentMode

2>设置内边距,不要太靠左代码  inset

3>设置lable和imageView的距离:

 

展开:可以点击,监听响应---

 

 

 

实现监听函数:(不一定非得)

-(void)layOutSubviews

#warning 一定需要调用父类的方法

{

[super layOutSubViews];

}

 

旋转:修改iamge的transform;

 

16:02展开与还原;

在init

设置视图的高度16:10两种方式:统一设,每个分步设

通过cell的高度的两种方式:

 

如何偷图片?展示类的app,720度旋转

docments 或者library

1>image

2>拿到image,托图片到资源

3>设默认图片;

4>拖动的时候重新设置一张图片

5>设置图片容器

创建触摸事件:平移的手势管理器

self代表self的某个方法(viewDidLoad)

让imageView可以和用户交互;

 

6>定义变量,当前是第几张;切换图片

通过手势管理器获取在平模上的坐标

图片不显示:删掉重新添加;

 

代理和通知的区别?

 

打印bounds和frame的值

NSLog(@"%@", NSStringFromCGRect(view.bounds));

*  但凡在iOS中,init方法创建出来的控件frame/bounds都是0

 

UITableViewCell

@property (nonatomic, readonly, retain) UIView      *contentView;

UITableViewHeaderFooterView

@interface UITableViewHeaderFooterView : UIView

@property (nonatomic, readonly, retain) UIView *contentView;

 

 

没有进入set方法,调用set方法的对象为空;

 

 

0428qq头像点击?  0428:-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 为甚么警告?//可能定义cell为另外的类型

+(instancetype)headerWithTableView:(UITableView *)tableView

{     //标记,出列,创建,放回

static  NSString *IDH = @"header";

MJHeaderView *header=[tableView  dequeueReusableHeaderFooterViewWithIdentifier:IDH];

if (nil == header) {

//若重新创建,是局部变量,执行完就销毁,返回的永远为空

MJHeaderView* header=[[MJHeaderView alloc]initWithReuseIdentifier:IDH];

}

NSLog(@"headerWithTableView\n");

return header;

}

 

 

+(instancetype)cellWithTableView:(UITableView*)tableView

{  //标记,出列,创建,放回

static NSString*ID = @"friend";

 

MJFriendCell* cell = [tableView dequeueReusableCellWithIdentifier:ID  ];

if (nil==cell)

{//MJFriendCell*  cell,不能重新创建,重新创建会返回为空

cell=[[MJFriendCell  alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];

}

return cell;

}

 

//0426qq

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

MJMessageFrame*mf=self.messageFrames[indexPath.row];   //[[MJMessageFrame  alloc]init];

// NSLog(@"%d",mf.cellheight);

MJMessageFrame*mf = [[MJMessageFrame  alloc]init]此处不能重新创建,

return  mf.cellheight;

}

 

 

[btn addTarget:self action:@selector(headerClick) forControlEvents:UIControlEventTouchUpInside];

不需要设代理,不需要设监听,直接可以用;

知识点:

1.如果界面上有不同视图组成不能使用uitableviewcontroller

2.imageveiw在storyboard中不能添加子控件

3.设置按钮图片如果想要原样显示设置为image即可,如果设置为background会自动拉伸

4.设置uitextfield的背景不能选择样式(border style)

5.通过代码自定义Cell;

 

 

3.1.2通过tag获取子控件赋值

UIImageView *iconView = (UIImageView *)[appView viewWithTag:55];

iconView.image = [UIImage imageNamed:appInfo.icon];

 

//        取出UILabel

UILabel *nameLabel = (UILabel *)[appView viewWithTag:100];

nameLabel.text = appInfo.name;

 

 

contentOffset位置修改,大图展示就实现滚动

 

图片轮播:实现原理??

 

 

#import "NJViewController.h"

 

@interface NJViewController () <UIScrollViewDelegate>

@property (weak, nonatomic) IBOutlet UIScrollView *scrollview;

/**

*  页码

*/

@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;

 

@property (nonatomic, strong) NSTimer *timer;

@end

 

@implementation NJViewController

 

- (void)viewDidLoad

{

[super viewDidLoad];

 

 

//    图片的宽

CGFloat imageW = self.scrollview.frame.size.width;

//    CGFloat imageW = 300;

//    图片高

CGFloat imageH = self.scrollview.frame.size.height;

//    图片的Y

CGFloat imageY = 0;

//    图片中数

NSInteger totalCount = 5;

//   1.添加5张图片

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

UIImageView *imageView = [[UIImageView alloc] init];

//        图片X

CGFloat imageX = i * imageW;

 

//        设置frame

imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);

 

//        设置图片

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

imageView.image = [UIImage imageNamed:name];

//        隐藏指示条

self.scrollview.showsHorizontalScrollIndicator = NO;

 

[self.scrollview addSubview:imageView];

}

 

//    2.设置scrollview的滚动范围

CGFloat contentW = totalCount *imageW;

self.scrollview.contentSize = CGSizeMake(contentW, 0);

 

//    3.设置分页

self.scrollview.pagingEnabled = YES;

 

//    self.pageControl.currentPage = 3;

 

//    4.监听scrollview的滚动    控制器的对象的地址传给了scrollView的代理的地址

//   控制器对象和scrollView指向同一对象

self.scrollview.delegate = self;

 

 

//    NSTimer // 定时器 适合用来隔一段时间做一些间隔比较长的操作

/*

NSTimeInterval:多长多件操作一次

target :操作谁

selector : 要操作的方法

userInfo: 传递参数

repeats: 是否重复

*/

//   self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];

[self addTimer];

 

}

 

- (void)nextImage

{

//    NSLog(@"切换图片");

//    1.获取页码

/*

if (self.pageControl.currentPage == 4) {

self.pageControl.currentPage = 0;

}else

{

//        假设当前是第0页   变成第一页,就会立刻把小红点变成第一页

self.pageControl.currentPage++;

}

*/

 

int page = self.pageControl.currentPage;

if (page == 4) {

page = 0;

}else

{

page++;

}

 

 

//    2.滚动scrollview

//    CGFloat x = self.pageControl.currentPage * self.scrollview.frame.size.width;

CGFloat x = page * self.scrollview.frame.size.width;

 

self.scrollview.contentOffset = CGPointMake(x, 0);

}

 

// scrollview滚动的时候调用

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

 

NSLog(@"滚动中");

//    计算页码

//    页码 = (contentoffset.x + scrollView一半宽度)/scrollView宽度

CGFloat scrollviewW =  scrollView.frame.size.width;

CGFloat x = scrollView.contentOffset.x;

int page = (x + scrollviewW / 2) /  scrollviewW;

self.pageControl.currentPage = page;

}

 

// 开始拖拽的时候fxs

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

//    关闭定时器(注意点; 定时器一旦被关闭,无法再开启)

//    [self.timer invalidate];

[self removeTimer];

}

 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

{

//    开启定时器

[self addTimer];

}

 

/**

*  开启定时器

*/

- (void)addTimer{

 

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

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

}

/**

*  关闭定时器

*/

- (void)removeTimer

{

[self.timer invalidate];

}

 

传智电台的作用:

- (void)viewDidLoad

{

[super viewDidLoad];

CGFloat lastY = self.lastBtn.frame.origin.y + self.lastBtn.frame.size.height + 10 /* + 44 */;

//     只要不横向滚动, 宽度可以设置为0

//    设置滚动范围

self.scrollview.contentSize = CGSizeMake(0, lastY);

 

//    2.为了不让导航view挡住scrollview

//    设置外边距

self.scrollview.contentInset = UIEdgeInsetsMake(64, 0, 44, 0);

 

//    设置contentOffset

//    1.取出以前的offset

CGPoint tempOffset = self.scrollview.contentOffset;

//    2.修改以前的位置

tempOffset.y = -64;

//    3.覆盖以前的offset

self.scrollview.contentOffset = tempOffset;

}

 

大图展示中修改contentOffset的值就可以实现滚动;

 

 

图片缩放:只要添加函数就可以完成缩放吗?

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

{

NSLog(@"开始缩放");

return self.imageView;

}

 

//缩放过程中调用

- (void)scrollViewDidZoom:(UIScrollView *)scrollView

{

NSLog(@"正在缩放");

}

 

 

/**

*  缩放结束时调用

*

*  @param scrollView 当前的scrollview

*  @param view       被缩放的view

*  @param scale      缩放的比例

*/

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale

{

NSLog(@"缩放结束");

NSLog(@"view = %@, scale = %.1f", view, scale);

}

 

typedef  enum {

MJMessageTypeMe=0,

MJMessageTypeOther

} MJMessageType;  不能定义再累扩展中,MJMessageType不会被发现?

 

 

打印frame利器:

NSStringFromCGAffineTransorm(CGAffineTransorm transform)

NSStringFromClass(<#__unsafe_unretained Class aClass#>)

NSStringFrom.....打印frame,size.point.aff,transfrom,

NSStringFromClass(<#__unsafe_unretained Class aClass#>)

NSStringFromCGSize(<#CGSize size#>)

NSStringFromCGPoint(<#CGPoint point#>)

NSStringFromCGAffineTransform(<#CGAffineTransform transform#>)

NSStringFromProtocol(<#Protocol *proto#>)

NSStringFromRange(<#NSRange range#>)

NSStringFromSelector(<#SEL aSelector#>)

NSStringFromUIEdgeInsets(<#UIEdgeInsets insets#>)

NSStringFromUIOffset(<#UIOffset offset#>)

NSStringFromUIOffset(<#UIOffset offset#>)

 

微博自己敲的错误总结:

1>在左上角显示头像的位置显示VIP是因为,显示头像赋值时,赋给的是vip图标;正文的字体,赋值给时间显示;

2>字体无显示,没有字体的frame:也是赋值frame的时候ok,传智frame的"过桥时"两个frame不是同一个;        NSLog(@"打印frame利器:%@",NSStringFromCGRect(self.pictureView.frame));

[NSStrin]

3>图片无显示,前面设置好frame,在最后显示的时候,没有将设置号的值赋值过去,传值环节出问题;

通过打印设置frame的最后一步确定;

 

instancetype 和  MJMessageCell的值 不能写错:instancetype不是UITableViewcell,

MJMessageCell  不要写为 uUITableViewcell

+( instancetype)cellWithTableView:(UITableView *)tableView

{

static  NSString *ID=@"message";

MJMessageCell *cell=[tableView  dequeueReusableCellWithIdentifier:ID];

if (cell == nil) {

cell = [[MJMessageCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];

}

return cell;

}

 

 

 

UIImageView *iconView = [[UIImageView  alloc]init];

[self.iconView  addSubview: iconView];

self.iconView = iconView;

 

self.iconView.image = [UIImage  imageNamed: @"me"];

_iconView.frame =messageFrame.iconF;

NSLog(@" self.iconView.frame = %@\n", NSStringFromCGRect(self.iconView.frame))  ;

NSLog(@"iconframe = %@\n",NSStringFromCGRect(messageFrame.iconF));

打印发现_iconView为nil 为nil说明是上一层的错误, 再找上一层,发现加控件错了;

[self.iconView  addSubview: iconView];

 

 

 

QQ发消息中键盘不能移动只是inputView移动到上面,改为view整体移动就解决问题了,view上面有tablView和view,所以让view整体,移动,

 

一个文本lable在没有写入文字的时候,给文字设置颜色,可能会没显示;或者设置的文字可能不成功; 9o

 

 

字典转模型:如果一个plist文件下面

 

汽车列表:plist=NSString*title +  NSArray*cars

 

- (instancetype)initWithDict:(NSDictionary *)dict

{

if (self = [super init]) {

self.title = dict[@"title"];

NSArray *dictArray = dict[@"cars"];

NSMutableArray *modles = [NSMutableArray  arrayWithCapacity:dictArray.count];

for (NSDictionary *dict in dictArray) {

MJCar *car = [MJCar  carWithDict:dict];

[modles addObject:car];

}

self.cars = modles;

}

return  self;

}

 

好友列表:plist 两个属性 +NSArray* friends

-(instancetype)initWithDict:(NSDictionary *)dict

{

if (self=[super  init])

{

//注入所有的属性   三个属性转化为字典

[self setValuesForKeysWithDictionary:dict];

//创建,遍历,转化,添加,赋值   处理特殊的属性

 

//下面的是补充转化,二次处理

NSMutableArray*models=[NSMutableArray arrayWithCapacity:self.friends.count];

//取出self.frends数组中的每个字典转化

for (NSDictionary*dict in self.friends) {

MJFriend*friend=[MJFriend  friendWithDict:dict];

[models addObject:friend];//medels是一个数组,转化后存放4个模型的数组

}

self.friends=models;//models        是模型数组,MJFriend中friend是转化后的模型数组:里面存放有很多单个模型

 

}

//返回的是一组模型;

return self;

}

 

 

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

{   //1.创建头部视图

MJHeaderView *header = [MJHeaderView  headerWithTableView:tableView];

//  header.userInteractionEnabled=YES;

MJFriendGroup *gp = self.groups[section];

header.group=gp;

//设置代理

header.delegate=self;

 

return header;

}

 

 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

{

//    1.取出对应的模型

NJCarGroup *cg = self.cars[section];

return cg.title;

}

 

 

设置每一行的高度:heightForRow

 

谁的代理方法用谁开头

刷新是relaod重新加载模型数据;

什么情况下使用tableViewController (只有tableView一种的情况) 和  MJViewController(界面情况比较复杂,不只tableView一种),怎么区分?

 

 

什么情况下用系统自带的cell,什么情况下需要自定义cell

1>类似于微博,QQ发消息,每个cell的内容都不一样的时候,无规律的时候需要自定义cell

2>类似团购,九宫格,自定义cell不能满足,但是数据之间是有规律的情况下使用xib,

3>像汽车品牌展示,英雄展示,QQ好友列表等,系统的subtitle,default,title等模式可以满足的情况下使用系统自带的cell

4>类似传智猜图,上半部分的界面固定使用storyBoard,下半部分的不固定使用代码实现,代码实现较麻烦,比较灵活

 

 

创建cell类,为cell赋值等一些操作;

 

 

 

0501KVC的本质:将字典中的键值为dict[@"name"]的对应的value  赋值给创建模型中属性名为name的值;

 

 

0501 好友列表中MJFriendGroup中setValuesForKeysForDict   这行=0504好友列表所示?(kvc的名字没有一一对应)

 

0504  控制器中,btw中设置 btn.titleLable.text  she设置了字体和颜色无法显示????区别

 

 

0504好友列表的头部视图点击原理待复习,bug待调试

 

/**

*  当视图的frame被修改的时候就会调用  ?没看见修改frame啊?(是在头部视图创建完成return header  并且设置了数据才调用,创建frame的时候默认有一个创建frame也算改变)

*  一般在这个方法中布局子控件

*/

- (void)layoutSubviews

{

#warning 一定要调用父类的改方法

[super layoutSubviews];

 

//    1.设置按钮的frame

self.btn.frame = self.bounds;

NSLog(@" = %@\n",NSStringFromCGRect(self.bounds));

//    2.设置label的frame

CGFloat labelY = 0;

CGFloat labelH = self.bounds.size.height;

CGFloat labelW = 50;

CGFloat labelX = self.bounds.size.width - 10 - labelW;

self.nameLabel.frame = CGRectMake(labelX, labelY, labelW, labelH);

}

 

 

 

#pragma mark - 当视图被添加到别的视图中的时候就会调用

- (void)didMoveToSuperview

{

// 修改三角形的旋转角度

//    NSLog(@"当前视图被添加到了其它视图中");

// 判断当前组是否展开

if (self.group.isOpened) {

//  展开状态

self.btn.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);

}else

{

// 合拢状态

self.btn.imageView.transform = CGAffineTransformIdentity;

}

}

 

 

 

//通知控制器刷新表格,看下self的代理是否实现了headerViewDidClicked:这个方法,如果实现了这个方法

// 就通知self的代理(指代控制器)  去调用headerViewDidClicked这个方法

if ([self.delegate  respondsToSelector:@selector(headerViewDidClicked:)])

{

[self.delegate headerViewDidClicked:self];

}

 

 

0504

pickerView  不用设宽高 拖数据源

自带的,连线不需要协议和设代理?类似UITableViewController

随机函数

self.foods.count

正确的:[self.foods  count]  错误:self.Foods[0].count     self.Foods[0]= [self.foods objectAtIndex 0]

objectAtIndex返回的是id类型的;

 

1029  1034作业

button里面

1056批量改类名(文件)技巧,变蓝色修改

pickerView设间距:行高高点54;

viewForRow一行出现视野会调用,类似cellforRow

 

dataPichker  改归属地

中文:model  date只显示日期

pick里面有最小时间和最大时间

 

textField  可以设置键盘的格式(时间选择器)

 

toolBar只能添加bar  button

添加别的自动包装成bar  button

 

barButton是有样式,在ios7无效

flexible  可拉升的;可以移到靠右;

 

屏幕的动态获取

self

1420的第三个自动拉升\

 

test  用在单元测试中,include  unitytest  xcode4中勾选之后才会出选test

prodecuts 文件对于ios是废物

 

ipone  正,左右,ipone  upsde down不支持

 

 

pch文件自动去掉nslog

开发:打印日志

打包:打包程序上传到appstore

pch文件:先看下公司是否有自定义的宏  ,nslog

自定义log

 

 

DEBUG 宏:(在公司不要使用nslog):(目前不要使用nslog,自定义log );

 

UIApplication 是应用程序的象征

UIApplication *app = [UIApplication sharedApplication];获得单利对象(程序启动创建的第一个对象);

 

UIApplication应用级别的操作,用应用A打开应用B,分享;

多个对象同一地址:单例

多次获取的地址都相同;

 

设置显示联网状态  看菊花

app.networkActivityIndicatorVisible = YES;

 

0代表 清除图标右上角的数字  998添加图标数字

app.applicationIconBadgeNumber = 0;

 

lightContent是白色的字体

 

app.statusBarStyle = UIStatusBarStyleLightContent;(修改状态栏样式)

 

[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];状态栏的动画

app.statusBarHidden = YES(所有的状态栏都会隐藏); 隐藏状态栏:动态的显示修改状态栏:(动态)

// URL : 一个资源的唯一路径

 

// URL的组成 == 协议头://主机域名/路径

 

网络资源URL的组成 == http(协议头)://www.baidu.com/1.png

 

// 本地文件资源URL的组成 == file:///Users/apple/Desktop/1.png(无资源地址,本地)

[app openURL:[NSURL URLWithString:@"http://ios.itcast.cn"]];

 

使用app打开网页

[app openURL:[NSURL URLWithString:@"http://ios.itcast.cn"]];

 

打电话

[app openURL:[NSURL URLWithString:@"tel://10086"]];

发短信

[app openURL:[NSURL URLWithString:@"sms://10086"]];

邮件

[app openURL:[NSURL URLWithString:@"Mailto://lnj@126.cn"]];

打开其他的应用程序

 

default.png 显示完毕,程序启动完毕

程序启动完毕后立即执行的指令:

程序进入后台执行的指令:这个方法通常在这个方法中保存应用信息

程序进入前台执行的方法;

重新获取焦点

即将失去焦点:失去焦点不能使用

 

 

 

 

iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了

 

一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow

 

也就说,没有UIWindow,就看不见任何UI界面

 

 

 

添加UIView到UIWindow中两种常见方式:

- (void)addSubview:(UIView *)view;

直接将view添加到UIWindow中,但并不会理会view对应的UIViewController

\@property(nonatomic,retain) UIViewController *rootViewController;

自动将rootViewController的view添加到UIWindow中,负责管理rootViewController的生命周期

 

常用方法

- (void)makeKeyWindow;

让当前UIWindow变成keyWindow(主窗口)

 

- (void)makeKeyAndVisible;

让当前UIWindow变成keyWindow,并显示出来

 

window view

谁是爸

1648 之间的关系,强应用,

 

只要有强引用使用对象,对象就不会释放,有强指针指着他;

 

hosring  文本换行或者特殊的字符youcompleteme插件,在vim中添加自动代码补全的功能;

 

 

建立一个工程后,会在Supporting files文件夹下看到一个“工程名-Info.plist”的文件,该文件对工程做一些运行期的配置,非常重要,不能删除

 

 

在旧版本Xcode创建的工程中,这个配置文件的名字就叫“Info.plist”

项目中其他Plist文件不能带有“Info”这个字眼,不然会被错认为是传说中非常重要的“Info.plist”

项目中还有一个InfoPlist.strings的文件,跟Info.plist文件的本地化相关

 

常见属性(红色部分是用文本编辑器打开时看到的key)

Localiztion native development region(CFBundleDevelopmentRegion)-本地化相关

 

Bundle display name(CFBundleDisplayName)-程序安装后显示的名称,限制在10-12个字符,如果超出,将被显示缩写名称

 

Icon file(CFBundleIconFile)-app图标名称,一般为Icon.png

 

Bundle version(CFBundleVersion)-应用程序的版本号,每次往App Store上发布一个新版本时,需要增加这个版本号

 

Main storyboard file base name(NSMainStoryboardFile)-主storyboard文件的名称

 

Bundle identifier(CFBundleIdentifier)-项目的唯一标识,部署到真机时用到

 

 

 

 

项目的Supporting files文件夹下面有个“工程名-Prefix.pch”文件,也是一个头文件

 

pch头文件的内容能被项目中的其他所有源文件共享和访问

 

一般在pch文件中定义一些全局的宏

 

在pch文件中添加下列预处理指令,然后在项目中使用Log(…)来输出日志信息,就可以在发布应用的时候,一次性将NSLog语句移除(在调试模式下,才有定义DEBUG)

#ifdef DEBUG

#define Log(...) NSLog(__VA_ARGS__)

#else

#define Log(...) /* */

#endif

 

 

设置应用程序图标右上角的红色提醒数字

@property(nonatomic) NSInteger applicationIconBadgeNumber;

 

 

 

 

设置联网指示器的可见性

@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

 

 

如果想利用UIApplication来管理状态栏,首先得修改Info.plist的设置

 

所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止

 

还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件

 

delegate可处理的事件包括:

应用程序的生命周期事件(如程序启动和关闭)

系统事件(如来电)

内存警告

… …

[self.foods[component] count]计算二维数组中某个一维数组的个数

 

 

 

/        3.让pickerview主动选中某一行某一列

[self.pickerView selectRow:newRow inComponent:component animated:YES];

 

//        通过代码让pickerview选中某一行不会调用代理的didSelectRow方法

 

//        4.手动调用didSelectRow方法(更改lable的文字)

[self pickerView:nil didSelectRow:newRow inComponent:component];

 

 

 

/**

pch文件的作用:

1.存放一些全局的宏(整个项目中都用得上的宏)

2.用来包含一些全部的头文件(整个项目中都用得上的头文件)

3.能自动打开或者关闭日志输出功能

*/

 

#import <Availability.h>

 

#ifndef __IPHONE_5_0

#warning "This project uses features only available in iOS SDK 5.0 and later."

#endif

// 写在__OBJC__里面的代码被所有的.m 和 .mm文件共享

// 以后所有和OC相关的东西都方法__OBJC__里面#ifdef __OBJC__ #endif  里面有嵌套

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

 

#define NUMBER 55

#import "NJPerson.h"

 

#ifdef DEBUG

#define NJLog(...) NSLog(__VA_ARGS__)

#else

#define NJLog(...)

#endif

 

#endif

 

// 写在__OBJC__外面的代码被所有的文件共享  里面外面怎么区分?

#define ABC 10

 

//#import "NJPerson.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

程序启动就执行

 

self.window.frame = [UIScreen mainScreen].bounds;(bounds从00开始?)

 

self.window = window;保存,使用强指针指向他,否则是局部变量

 

MjOneViewController *one = [[MjOneViewController alloc] init];

//    [self.window addSubview:one.view];

self.window.rootViewController = one;

两种的区别:0921选装,更着转,强弱应用

 

程序启动

老师笔

MjOneViewController *one = [[MjOneViewController alloc] init];

//    [self.window addSubview:one.view];

self.window.rootViewController = one;

 

一.UIPickerView

1.UIPickerView的常见属性

// 数据源(用来告诉UIPickerView有多少列多少行)

@property(nonatomic,assign) id<UIPickerViewDataSource> dataSource;

// 代理(用来告诉UIPickerView每1列的每1行显示什么内容,监听UIPickerView的选择)

@property(nonatomic,assign) id<UIPickerViewDelegate>   delegate;

// 是否要显示选中的指示器

@property(nonatomic)        BOOL                       showsSelectionIndicator;

// 一共有多少列

@property(nonatomic,readonly) NSInteger numberOfComponents;

 

2.UIPickerView的常见方法

// 重新刷新所有列

- (void)reloadAllComponents;

// 重新刷新第component列

- (void)reloadComponent:(NSInteger)component;

 

// 主动选中第component列的第row行

- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated;

 

// 获得第component列的当前选中的行号

- (NSInteger)selectedRowInComponent:(NSInteger)component;

 

3.数据源方法(UIPickerViewDataSource)

//  一共有多少列

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

//  第component列一共有多少行

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

 

4.代理方法(UIPickerViewDelegate)

//  第component列的宽度是多少

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component;

//  第component列的行高是多少

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component;

 

//  第component列第row行显示什么文字

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

 

//  第component列第row行显示怎样的view(内容)

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;

 

//  选中了pickerView的第component列第row行

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

 

二.UIDatePicker

1.常见属性

// datePicker的显示模式

@property (nonatomic) UIDatePickerMode datePickerMode;

// 显示的区域语言

@property (nonatomic, retain) NSLocale   *locale;

 

2.监听UIDatePicker的选择

* 因为UIDatePicker继承自UIControl,所以通过addTarget:...监听

 

三.程序启动的完整过程

1.main函数

 

2.UIApplicationMain

* 创建UIApplication对象

* 创建UIApplication的delegate对象

 

3.delegate对象开始处理(监听)系统事件(没有storyboard)

* 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法

* 在application:didFinishLaunchingWithOptions:中创建UIWindow

* 创建和设置UIWindow的rootViewController

* 显示窗口

 

3.根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard(有storyboard)

* 创建UIWindow

* 创建和设置UIWindow的rootViewController

* 显示窗口

keyWindow:键盘显示的window

让window成为keyWindow(主窗口)

//    [self.window makeKeyWindow];并不会显示,只是成为主要window

// 让window成为keyWindow(主窗口)\并且可见

[self.window makeKeyAndVisible];

//    self.window = window;(强指针保存,否则局部销毁)

0920平模旋转事件过程

.keyWindow

[UIApplication sharedApplication].keyWindow);获取主UIWindow

 

主window接受键盘点击

uitextField默认透明

tf.borderStyle = UITextBorderStyleRoundedRect;

 

ios7之前只有keywindow才能接受键盘输入和触摸

ios7 之后

根控制器

 

 

NSLog(@"%@", [UIApplication sharedApplication].windows);

获取所有的window

 

键盘处在一个独立的window中

获取键盘的view 从而自定义

 

 

layoutSubviews

在创建的时候,自动赋值frame,相当于改变了frame所以会调用

1016?

主窗口才能接受键盘

 

 

一个window只能有一个跟控制器

 

 

控制器常见的创建方式有以下几种

通过storyboard创建,创建,添加

 

直接创建

MJViewController *mj = [[MJViewController alloc] init];

 

指定xib文件来创建

MJViewController *mj = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];

 

 

系统创建控制器

控制器的三种创建方式

 

fiesOwner

里面的class设置为那个控制器(类名),就可以为那个控制器服务,连线fileowner

 

 

11:38总结0506  view创建的八种方式

控制器的view 加载;

 

 

 

UINavigationController的使用步骤

初始化UINavigationController

设置UIWindow的rootViewController为UINavigationController

根据具体情况,通过push方法添加对应个数的子控制器

导航条44:20导航栏

导航控制器通过栈的形式管理子控制器

 

当前看到的是栈顶的控制器

push移开,back  控制器和view 销毁

 

autolayOut  子控件的不现实,或者结果不对的时候,去掉autolayOUt的沟,否则一个控件移动他会自动布局,影响结果;

 

导航控制器的栈两种形式

root控制器栈低的控制器

栈顶的.nav  topView

 

放回出栈,前进进栈;

[控制器  popView ]移除栈顶的控制器

根=栈低

pop  出移除 push推入

程序加载完毕:viewDidLoad

self.UINavigationItem.title

 

返回按钮不是当前的控制器,是有上一个控制器决定,其他的都是当前控制器决定

nav.UINavigationBar.frame 打印frame

1616?为什么拖nav

storyBoard 拖线不能往回拖

 

viewWillUnload  即将销毁的时候调用

viewDidUnload   完全销毁

配合内存警告使用

 

 

 

 

// 创建控制器

NJViewController *vc = [[NJViewController alloc] init];

 

// 添加控制器的view到window上面

// 这种方式不好,不推荐

//    [self.window addSubview:vc.view];  view添加后被强引用着,NJViewController的对象会被提前释放

 

 

 

// 设置window的根控制器

self.window.rootViewController = vc;

 

// 3.显示window

[self.window makeKeyAndVisible];

return YES;

 

 

 

打印方法(当前的window和rootController)

NSLog(@"self.Window = %@\n",self.window);

NSLog(@"rootControl = %@\n",self.window.rootViewController);

 

创建一个控制器 如果没指定跟控制器,会是默认的白色,即使给控制器的View设置有颜色;

 

outlet连线

链接folesOwner作用是什么这只self.view

 

 

从xib中加载storyBoard  拖两个view 更改xib所属的类名(控制器的类),当有两个view的时候

 

那个控制器是根控制器,那么就显示根控制器的颜色

 

storyBoard的本质是将storyBoard转化为代码

 

 

//  nav.viewControllers == nav.childViewControllers

 

//常用

 

 

创建window必须得初始化frame 否则上面的控件不显示,或者不起作用

 

 

遍历出UIView中的所有子控件;并将遍历的结果写入文件

- (void)applicationDidBecomeActive:(UIApplication *)application

{

 

NSString *xml =  [self digView:self.window];

[xml writeToFile:@"/Users/wg689/Desktop/ios6.xml" atomically:YES];

 

}

// 取出window中所有的子控件 以及他们的frame

- (NSString *)digView:(UIView *)view

{

if ([view isKindOfClass:[UITableViewCell class]]) return @"";

// 1.初始化

NSMutableString *xml = [NSMutableString string];

 

// 2.标签开头

[xml appendFormat:@"<%@ frame=\"%@\"", view.class, NSStringFromCGRect(view.frame)];

if (!CGPointEqualToPoint(view.bounds.origin, CGPointZero)) {

[xml appendFormat:@" bounds=\"%@\"", NSStringFromCGRect(view.bounds)];

}

 

if ([view isKindOfClass:[UIScrollView class]]) {

UIScrollView *scroll = (UIScrollView *)view;

if (!UIEdgeInsetsEqualToEdgeInsets(UIEdgeInsetsZero, scroll.contentInset)) {

[xml appendFormat:@" contentInset=\"%@\"", NSStringFromUIEdgeInsets(scroll.contentInset)];

}

}

 

// 3.判断是否要结束

if (view.subviews.count == 0) {

[xml appendString:@" />"];

return xml;

} else {

[xml appendString:@">"];

}

 

// 4.遍历所有的子控件

for (UIView *child in view.subviews) {

NSString *childXml = [self digView:child];

[xml appendString:childXml];

}

 

// 5.标签结尾

[xml appendFormat:@"</%@>", view.class];

 

return xml;

}

 

0508预习笔记

在恰当的时刻,使用perform方法执行对应的Segue

[self performSegueWithIdentifier:@"login2contacts" sender:nil];?

// Segue必须由来源控制器来执行,也就是说,这个perform方法必须由来源控制器来调用

利用performSegueWithIdentifier:方法可以执行某个Segue(继续==线对象),完成界面跳转

 

如果点击某个控件后,需要做一些判断,也就是说:满足一定条件后才跳转到下一个界面,建议使用“手动型Segue”

 

 

接下来研究performSegueWithIdentifier:sender:方法的完整执行过程

[self performSegueWithIdentifier:@“login2contacts” sender:nil(/*同对象*/)];

// 这个self是来源控制器

1>找到线,新建  2>设置来源和目标

根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象

设置Segue对象的sourceViewController(来源控制器)

新建并且设置Segue对象的destinationViewController(目标控制器)

 

跳转的步骤:

1>准备,创建对象

调用sourceViewController的下面方法,做一些跳转前的准备工作并且传入创建好的Segue对象

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender(/*同对象*/);

// 这个sender是当初performSegueWithIdentifier:sender:中传入的sender

2>开始跳转

调用Segue对象的- (void)perform;方法开始执行界面跳转操作

3>取得导航控制器

取得sourceViewController所在的UINavigationController

4>压栈 完成跳转

调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转

 

跟UINavigationController(导航控制器)类似

,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是QQ、微信等应用

 

 

每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒

应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Layer)

模拟器应用沙盒的根路径在: (apple是用户名, 6.0是模拟器版本)

/Users/apple/Library/Application Support/iPhone Simulator/6.0/Applications

 

// 应用沙盒的结构分析:

1>应用程序包:(上图中的Layer)包含了所有的资源文件和可执行文件

2> Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录

 

3> tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录

 

4> Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据

 

5> Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录

 

 

沙盒根目录:NSString *home = NSHomeDirectory();

 

Documents:(2种方式)

利用沙盒根目录拼接”Documents”字符串

NSString *home = NSHomeDirectory();

NSString *documents = [home stringByAppendingPathComponent:@"Documents"];

// 不建议采用,因为新版本的操作系统可能会修改目录名

利用NSSearchPathForDirectoriesInDomains函数

// NSUserDomainMask 代表从用户文件夹下找

// YES 代表展开路径中的波浪字符“~”

NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask<代表从用户文件夹下找>, NO<不展开路径的波浪字符>);

// 在iOS中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素

NSString *documents = [array objectAtIndex:0];

 

 

0508私人通讯录

1>界面搭建

多个控制器,使用导航来管理其他的控制器

2>登陆界面(viewController,普通View界面)  ,联系人界面(继承UItableView),添加联系人界面(继承View 不可以滚),编辑界面(不可以滚,普通的view),

3>登陆界面(viewController,普通View界面),设置rootView(拖view 的线),一个整体就放在view上,(使用view来管理子控件).title(双击头部标题)

4>要获得属性监听->连线,刚开始btn不能点:enable 去掉沟

5>监听方式选择(输入文本框):addTarget一般监听按钮的点击,以及进度条值的改变(无方法),  --代理(中没有UItextFieldDelegate中没有监听输入框值改变的方法)  --通知

6>  [[NSNotificationCenter defaultCenter](创建通知中心) addObserver:self (谁来监听)selector:@selector(textChange(接到通知后执行的操作)) name:UITextFieldTextDidChangeNotification(通知名称) object:self.pwdField(谁发送的通知)(nil代表谁发送都可以接受通知,此处不能写nil,只能接受两个,不是多个的通知)];

UITextFieldTextDidChangeNotification(输入框改变的时候会发出此通知)

7>拖线自动登录,记住密码

8>登录做完,做联系人列表,拖下一个界面;

9>数据传递

10>判断是否登录正确:连线,监听:如果正确

 

 

 

 

拖不了线===没建立关系:类名

不需要参数就手写代码

alert弹框显示:show一下

弹框:UIActionSheet   1>创建  2>显示:showInView

避免每次输入密码:直接修改代码:输入数据确定,免得每次输入

 

btn.enable =YES;代表btn可以用,

placeHolder   输入框提示:(*)必填

暗文  secure

UISwith和按钮一样:

 

segue:身份,来自哪,去哪;

手动的:控制器拖到控制器(表面上看是View);

 

自动:控件到控制器

coco4app  加快工作效率

封装:->

 

 

/**

*  执行segue后,跳转之前会调用这个方法

*  一般在这里给下一个控制器传递数据

*/

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

{

// 1.取得目标控制器(联系人列表控制器)

UIViewController *contactVc = segue.destinationViewController;

 

// 2.设置标题

contactVc.title = [NSString stringWithFormat:@"%@的联系人列表", self.accountField.text];

// contactVc.title 等价于 contactVc.navigationItem.title

//    contactVc.navigationItem.title = [NSString stringWithFormat:@"%@的联系人列表", self.accountField.text];

}

 

 

需要修改cpntroller的类;下一个控制器:的返回上个控制器决定,copy 代码  不会拷贝连线

 

通知不用需要移除

让键输入框成为第一响应者:就可以立即召唤出键盘

让姓名

 

stro  xib创建的都不会调用init方法

 

如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复(不能写归档)

不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以

NSCoding协议有2个方法:

encodeWithCoder:

每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量

initWithCoder:

每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量

 

 

NSString *home = NSHomeDirectory();

 

// 2.document路径

NSString *docPath = [home stringByAppendingPathComponent:@"Documents"];

 

// 3.新建数据

//    MJPerson *p = [[MJPerson alloc] init];

//    p.name = @"rose";

NSArray *data = @[@"jack", @10, @"ffdsf"];

 

 

// 1.利用NSUserDefaults,就能直接访问软件的偏好设置(Library/Preferences)

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

 

 

// 3.立刻同步:保存数据

[defaults synchronize];

 

发送未识别的消息.没有那个方法(找不到这个方法);

 

 

 

- (IBAction)save {

// 1.新的模型对象

MJStudent *stu = [[MJStudent alloc] init];

stu.no = @"42343254";

stu.age = 20;

stu.height = 1.55;

 

// 2.归档模型对象

// 2.1.获得Documents的全路径

NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

// 2.2.获得文件的全路径

NSString *path = [doc stringByAppendingPathComponent:@"stu.data"];

// 2.3.将对象归档

[NSKeyedArchiver archiveRootObject:stu toFile:path];

}

 

- (IBAction)read {

// 1.获得Documents的全路径

NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

// 2.获得文件的全路径

NSString *path = [doc stringByAppendingPathComponent:@"stu.data"];

 

// 3.从文件中读取MJStudent对象

MJStudent *stu = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

 

NSLog(@"%@ %d %f", stu.no, stu.age, stu.height);

}

 

 

/**

*  将某个对象写入文件时会调用

*  在这个方法中说清楚哪些属性需要存储

*/

- (void)encodeWithCoder:(NSCoder *)encoder

{

[encoder encodeObject:self.no forKey:@"no"];

[encoder encodeInt:self.age forKey:@"age"];

[encoder encodeDouble:self.height forKey:@"height"];

}

 

/**

*  从文件中解析对象时会调用

*  在这个方法中说清楚哪些属性需要存储

*/

- (id)initWithCoder:(NSCoder *)decoder

{

if (self = [super init]) {

// 读取文件的内容

self.no = [decoder decodeObjectForKey:@"no"];

self.age = [decoder decodeIntForKey:@"age"];

self.height = [decoder decodeDoubleForKey:@"height"];

}

return self;

}  extern

 

 

父页面是tableViewceller,父父页面是navigationer,子页面 tableViewceller,父子页面之间没连线的时候,子页面的tableViewcontroll是无法显示导航条的标题的

 

英文的时候可以本地化里面修改,sh

 

导航上添加按钮:通过代码

 

tableView重新显示:两个步骤:

1>增加模型

2>刷新表格

3>持久化数据

 

每个Cell 有 contenTView =图像+text  +text

 

 

 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

 

/*

// 1.没有xib和storyboard的情况(默认会创建一个空白色view)

NJOneViewController *one = [[NJOneViewController alloc] init];

one.view.backgroundColor = [UIColor redColor];

*/

 

/*

// 2.通过storyboard创建(会去storyboard中创建剪头指向的view)

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];

NJOneViewController *one = [storyboard instantiateInitialViewController];

*/

/*

// 3.指定xib的情况(去xib中创建files onwner 的view属性连接的view)

NJOneViewController *one = [[NJOneViewController alloc] initWithNibName:@"Demo" bundle:nil];

*/

 

/*

// 4.有同名xib的情况 (自动加载同名的xib,创建xib中files onwner 的view属性连接的view)

NJOneViewController *one = [[NJOneViewController alloc] init];

*/

 

 

/*

// 5.有同名xib的情况,xib名称是去掉controller的情况 ((自动加载去掉controller的xib,创建xib中files onwner 的view属性连接的view)

NJOneViewController *one = [[NJOneViewController alloc] init];

*/

 

// 6.如果重写了控制器的loadview方法,就不会自动去加载xib

//NJOneViewController.xib

NJOneViewController *one = [[NJOneViewController alloc] init];

 

/*

//7.如果重写了控制器的loadview方法,就不会自动创建storyboard中剪头指向的view

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];

NJOneViewController *one = [storyboard instantiateInitialViewController];

*/

 

// 8.如果重写了控制器的loadview方法, 并且在loadview方法中创建了uiview,就会显示loadview中的uiveiw,不会再去创建其它(xib,storyboard)的veiw

//     NJOneViewController *one = [[NJOneViewController alloc] init];

 

self.window.rootViewController = one;

[self.window makeKeyAndVisible];

return YES;

}

 

 

添加tabBar是controller;添加子控制器

控制器包含view

 

如何验证控制器是否创建:重写生命周期方法

子类都用用到某一个,抽取父类

 

该继承,改一个就行

重新创建调用:viewDidload

 

did

- (void)applicationDidBecomeActive:(UIApplication *)application

获取焦点,程序可用,可以点

 

 

tabBar  控制器   封装导航控制器

导航栏,由栈顶控制器管理

返回上一个控制器决定

hideTabar  设置那个界面的tabarbtn的属性

跟控制器不能hideTabar

14:30修改?

不显示,删掉数据源:为0;  导航会执行默认的方法

 

model  遮盖,盖住原来的控制器

 

toot展示的控制器,虽说显示two,root还是 one

 

弱指针  一创建就是放

 

 

strong   只要我在,你得在,在其他的地方还可以使用

weak   避免我销毁了,你还不销毁,造成内存泄露

 

 

 

 

归档:

- (IBAction)saveBtnClick:(id)sender {

// 创建对象

NJPerson *p = [[NJPerson alloc] init];

p.name = @"lnj";

p.age = 29;

p.height = 1.75;

 

// 获取目录

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSLog(@"docPath = %@\n",docPath);

NSString *filePath = [docPath stringByAppendingPathComponent:@"arc.xxoo"];

NSLog(@"filePath = %@\n",filePath);

 

 

// 保存自定义对象(归档)

[NSKeyedArchiver archiveRootObject:p toFile:filePath];

 

}

 

- (IBAction)readBtnClick:(id)sender {

 

// 获取目录

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSString *filePath = [docPath stringByAppendingPathComponent:@"arc.xxoo"];

// 解归档

NJPerson *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

NSLog(@"%@, %d, %.1f", p.name, p.age, p.height);

}

 

 

私人通讯录:键盘文字改变的时候,让添加姓名的按钮变为可用,涉及通知:addtarget  :代理,通知三种办法;

self.nameField  addTarget:self(添加到当前控制器) action:执行的操作 forControlEvents:<#(UIControlEvents)#>(什么事件,)

当self.nameField

 

//addTarget:一般用于监听按钮的点击 以及进度条值的改变

//    self.nameField addTarget:self action:@selector() forControlEvents:UIControlEvent

 

// self.nameField.delegate = self;

 

// 通过通知监听UITextfield的改变

/*

addObserver: 谁来监听

selector: 通知发生的时候调用什么方法

name:通知名称

object:谁发送的通知

注意:object不能写nil, 因为如果是nil只要是UITextField发生改变都会调用textChange方法, 而我们指向账号和密码输入框发生改变的时候才调用

*/

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.nameField];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextFieldTextDidChangeNotification object:self.pwdField];

 

@property(nonatomic,assign) id<UITextFieldDelegate> delegate;

- (void)textFieldDidBeginEditing:(UITextField *)textField;           // became first responder

 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;   // return NO to not change text

{

代理不行

}

 

通知的使用:

1>如果继承于UIControl :使用addTarget(看下里面是否有)

2>看一下UITextFiled中有没有方法

3>看下通知:NSUITextField,通知名称:UITextField

 

//只要通过xib或者stotyBoard创建的cell都会调用这个方法

 

- (void) awakeFromNib

 

// 当控件的frame被修改就会调用

- (void)layoutSubviews

{

 

 

 

0511 qua2d

形上下文(Graphics Context):是一个CGContextRef类型的数据

 

图形上下文的作用

保存绘图信息、绘图状态

决定绘制的输出目标(绘制到什么地方去?)

(输出目标可以是PDF文件、Bitmap或者显示器的窗口上)

相同的一套绘图序列,指定不同的Graphics Context,就可将相同的图像绘制到不同的目标上

Quartz2D提供了以下几种类型的Graphics Context:

Bitmap Graphics Context

PDF Graphics Context

Window Graphics Context

Layer Graphics Context

Printer Graphics Context

 

layer控件能显示就因为这个

如何利用Quartz2D自定义view?(自定义UI控件(因为有layer))

 

如何利用Quartz2D绘制东西到view上?

1> 首先,得有图形上下文,因为它能保存绘图信息,并且决定着绘制到什么地方去

2>其次,那个图形上下文必须跟view相关联,才能将内容绘制到view上面 联系点   Layer Graphics Context(建立联系bug点)

 

自定义view的步骤

新建一个类,继承自UIView(bug点)

实现- (void)drawRect:(CGRect)rect方法 只有这个方法获得Layer Graphics Context ,然后在这个方法中

取得跟当前view相关联的图形上下文

绘制相应的图形内容

利用图形上下文将绘制的所有内容渲染显示到view上面

 

为什么要实现drawRect:方法才能绘图到view上?

因为在drawRect:方法中才能取得跟view相关联的图形上下文

 

drawRect:方法在什么时候被调用?

当view第一次显示到屏幕上时(被加到UIWindow上显示出来)

调用view的setNeedsDisplay或者setNeedsDisplayInRect:时

 

Quartz2D的API是纯C语言的

 

Quartz2D的API来自于Core Graphics框架

 

 

数据类型和函数基本都以CG作为前缀

CGContextRef

CGPathRef

CGContextStrokePath(ctx);

……

 

 

在drawRect:方法中取得上下文后,就可以绘制东西到view上

 

View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了

View之所以能显示东西,完全是因为它内部的layer

 

创建类继承UIView 同时storyBoard中更改类名

 

 

// 1.获得图形上下文  typedef struct CGContext *CGContextRef;

CGContextRef ctx = UIGraphicsGetCurrentContext()不需要星??

 

2>起点终点

3>上下文输出;

 

绘图和颜色的线的类型一致

// set : 同时设置为实心和空心颜色

// setStroke : 设置空心颜色

// setFill : 设置实心颜色

 

 

图形填充得边缘

 

 

 

 

1140?小细节

 

 

 

数码取色器

 

 

#define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]

 

.0没有没颜色

 

 

 

图形上下文:

获取图形上下文

 

 

上下文栈结束的地方

 

quas2dX

加班,复用性很差,模拟;传感器,物联网gps定位;

 

ios leader  ui 网络多线程,基本的(技术);工具类常用的东西,cto 主要技术负责人;那个模块细节的问题;ui改动需求,细节问题,需求

社交,网络多线程,实际的价值; 前期:ui高级  高级最后的  关于细节的问题,项目,新浪微博,细节的东西,

 

工具类封装;座位的事;自己组团;//自己

填充在剪切之后调用

自定义UIImageView

 

 

png 浏览器;搜图片

 

 

NSTimer 定时的更新数据;

CADisplayLink 更新动画的时候调用,一秒调用60次;

 

arc中通过C语言创建的函数,如果函数中保存create,retain,copy  必须调用release;

CGContextRef ctx =CGPathCreateMutable();需要释放内存

 

 

0512彩票

 

导航控制器copy  viewControllers

1>资源

2>图标  application

3>去掉玻璃球prerender ,使其扁平化 勾选去掉玻璃花效果(删去程序,点文件夹再沟),IOS5之前在配置文件中加一个行见0512的彩票视频

4>lanch 上面下面的黑,改Jasonios7 让其有四村的图片;

5>启动去掉状态栏  去掉沟,启动时全屏  general里面,

6>导航控制器设置根控制器

7点击的时候隐藏下面的工具条hidden

 

- (void)setHighlighted:(BOOL)highlighted

{

//重写这个方法让按钮normal - highlight(使这个为瞬态) -disable

// [super setHighlighted:YES];//设置按钮为高亮状态

}

 

系统ios6

 

设置状态栏颜色0935,如何看??只能通过application,

 

ios 6  适配

状态栏的设置批量在主题里面设置;

 

guide -- 经验-- UTransition??

 

1038看文档??如何分析??

strory 里面勾选界面

 

+initia

 

1156如何调bug

sdk 7.1  才能调用ios7 的方法;

编译器适配:

#ifdef _

 

else

 

shift  等比例缩放

ios6   00 与  ios7 00 1433总结  结构 器之间???

st里面的上下扩展,修改了相对的0点

在ios7 6  垂直方向都不变

scollView 做穿透  :不是scroolView 的时候,直接都去掉沟

 

UIStoryboard  里面也可以拉,strch 只有imageView可以拉伸

class 懒加载  小写的class

1>代码优化:使某些不可以点击

2>

 

指向函数:

block  本质是内敛函数,初学可以理解为宏定义,在编译的时候可以替换宏名

block使用copy

=1113之前的没听打电话去了;

创建xib 的时候需要制定重用的标示;'

xib和peng 不需要后缀

拖con了特殊cell   inset

item  =row

maskToBounds

 

 

#import "MJSettingItem.h"

 

@implementation MJSettingItem

 

+(instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title destVc:(Class)destVc

{

 

#warning item还是self

//创建item,使用self可以item???

MJSettingItem *item = [[self alloc] init];

item.icon = icon ;

item.title = title ;

item.destVc = destVc;

return item;

 

}

 

NSProxy.h

class

Returns self (the class object).  返回自己,返回类对象

 

+ (Class)class

Return Value  这是类方法  返回类对象

 

@property(nonatomic,assign) Class  destVc;  class 类方法>

 

一个界面对应一个控制器

 

loadView 装载的时候,直接复制webView 重写loadView

0920为什么要强转

控制器包装成导航控制器

 

 

父类对象指向子类需要强转

JavaScript  写对几条就编译几条

1015使用javascript

 

typeof (10)  = int  动态的获取某个变量的类型

typeof self;

 

 

- (void)viewDidLoad

{

[super viewDidLoad];

 

// 把self变成弱指针

// __unsafe_unretained 修饰的如果对象释放了, 变量依然指向释放前的地址

// __unsafe_unretained NJShareViewController *unRetainSelf = self;

//  __weak 修饰的如果对象释放了, 变量自动指向nil

// __weak NJShareViewController *unRetainSelf = self;

 

__weak typeof(self) unRetainSelf = self;//获取self的类型

 

//    int a = 5;

//    typeof(100) b  = 5;

 

// Do any additional setup after loading the view.

NJSettingItem *item0 = [NJSettingArrowItem itemWithIcon:nil title:@"新浪微博" destVc:nil];

NJSettingItem *item1 = [NJSettingArrowItem itemWithIcon:nil title:@"短信分享" destVc:nil];

item1.option = ^{

if (![MFMessageComposeViewController canSendText]) return;

MFMessageComposeViewController *vc = [[MFMessageComposeViewController alloc] init];

// 设置短信内容

vc.body = @"吃饭了没?";

// 设置收件人列表

vc.recipients = @[@"10010", @"123456"];

// 设置代理

vc.messageComposeDelegate = unRetainSelf;

 

// 显示控制器

[unRetainSelf presentViewController:vc animated:YES completion:nil];

 

sel.age = 10;

// _age = 10;

// self->_age = 10;

 

};

 

0519触摸

 

当前的控制器有group;

NJSettingGroup *group = [[NJSettingGroup alloc] init];

@property (nonatomic, strong) NSArray *items;

 

group.items = @[item0, item1, item2];(数组strong)

item2.option = ^{        // 设置代理

vc.mailComposeDelegate = self;}(这个中又有self  组成强应用的闭环)

在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象”

 

UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件

 

UIResponder内部提供了以下方法来处理事件

触摸事件

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

 

加速计事件

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;

 

远程控制事件

- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

 

UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件

一根或者多根手指开始触摸view,系统会自动调用view的下面方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

 

一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

 

一根或者多根手指离开view,系统会自动调用view的下面方法

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

 

触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

 

提示:touches中存放的都是UITouch对象

触摸:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

 

touchesBegan->touchesMoved->touchesEnded(必须的过程)

 

当用户用一根触摸屏幕时,会创建一个与手指相关联的UITouch对象

mutiple touch 勾选  支持多点触摸

一个手指对应一个touch对象

// 当前触摸点

CGPoint current = [touch locationInView:superView];//self];

// 上一个触摸点

CGPoint previous = [touch previousLocationInView:self];

 

为什么不精准??

 

一次完整的触摸过程,会经历3个状态:

触摸开始:- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

触摸移动:- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

触摸结束:- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

触摸取消(可能会经历):- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

 

4个触摸事件处理方法中,都有NSSet *touches和UIEvent *event两个参数

一次完整的触摸过程中,只会产生一个事件对象,4个触摸方法都是同一个event参数

 

如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象

 

如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象

 

根据touches中UITouch的个数可以判断出是单点触摸还是多点触摸

 

NSString通过代码创建

- (id)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self) {

[self setup];

}

return self;

}

//通过文件创建

- (id)init(O_O)?WithCoder:(NSCoder *)aDecoder

{

if (self = [super initWithCoder:aDecoder]) {

[self setup];

}

return self;

}

事件传递面试cha,子控件没有实现touchBegin方法,会将事件传递给父控件

什么是响应者链条

应用场景

怎么响应的??

面试常考?????响应者链条视频面试常考

 

UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势

这个类不能创建对象

 

代理名称:UI   ,方法去掉UI

美术,图书故宫,汽车,快用苹果助手    显示包内容:那图片

搜简历  看简历,企业账号,看简历的账号

 

 

 

 

 

夏国华:2011ios开发

什么是响应者链条:由响应者组成的链条

什么是响应者:继承UIrespond的对象

如何响应:自己是不是控制器的view ?(自己问自己的问题,响应者的方法:三个触摸的方法;能够响应就是实现了touch的三个方法) 不是  传给父控件,是   传给控制器

父控件或控制器没有实现触摸响应的事件,继续上传,直到找不到那么就丢弃

 

响应者的应用场景:在子控件中让父控件也响应触摸事件,在子控件的方法中调用父控件的触摸方法,并且把子空间传上去;

 

触摸事件的传递:从父控件传到子控件,如何找到最合适的控件来处理事件?

自己是否能接收触摸事件?

触摸点是否在自己身上?

从后往前遍历子控件,重复前面的两个步骤

如果没有符合条件的子控件,那么就自己最适合处理

 

 

UISwipeGestureRecognizer *swipGesture1 = [[UISwipeGestureRecognizer  alloc] initWithTarget:self action:@selector(swipView:)];

添加监听事件:会将swipGesture当做参数传给swipView 的参数

 

 

autoLayout  去掉才会出现:自动边缘四周的画面

 

 

 

 

//----------代理传值方法总结------------代理传值方法总结----------代理传值方法总结-------------

//这里的btn点击了,调用代理执行方法把btn作为参数,btn.tag

//传给实现代理的对象在代理对象中拿到这个tag的值进行一些操作

//            NJTabBar.m文件

- (void)btnOnClick:(UIButton *)btn

{

// -1.通知代理

if ([self.delegate respondsToSelector:@selector(tabBar:from:to:)]) {

[self.delegate tabBar:self from:self.currentSelectBtn.tag to:btn.tag];

}

//            NJTabBar.h文件

@class NJTabBar;

@protocol NJTabBarDelegate <NSObject>

- (void)tabBar:(NJTabBar *)tabBar from:(NSInteger)from to:(NSInteger)to;

@end

@interface NJTabBar : UIView

@property (nonatomic, weak) id<NJTabBarDelegate> delegate;

@end

 

#import "NJTab BarController.h"

NJTabBarController.m 文件  遵守代理代理:

@interface NJTabBarController ()<NJTabBarDelegate>

 

#pragma mark - NJTabBarDelegate //实现这个代理方法

- (void)tabBar:(NJTabBar *)tabBar from:(NSInteger)from to:(NSInteger)to

{

// 切换子控制器

self.selectedIndex = to;

}

 

//-------代理传值方法总结--------代理传值方法总结-------------代理传值方法总结-----------------

 

 

子类继承父类先调用子类的方法再调用父类的方法(如果子类中有函数调用super的方法会去父类中调用父类的方法)

 

UIView先绘制在图层上,系统将图层显示在屏幕上

 

layer.contents =(id) [UIImage  imageNamed:@"12"].CGImage;

 

 

UIView和CALayer的选择

通过CALayer,就能做出跟UIImageView一样的界面效果

 

既然CALayer和UIView都能实现相同的显示效果,那究竟该选择谁好呢?

其实,对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以

所以,如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以

当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级

 

每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)

 

 

 

所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画

 

什么是隐式动画?

当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果

而这些属性称为Animatable Properties(可动画属性)

 

列举几个常见的Animatable Properties:

bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画

backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画

position:用于设置CALayer的位置。修改这个属性会产生平移动画

 

 

返回按钮由上一个控制器决定;在上一个控制器setback,

CAPropertyAnimation的子类

属性解析:

fromValue:keyPath相应属性的初始值

toValue:keyPath相应属性的结束值

随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue

如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0)

 

//           UIView  与图层的关系?

当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示

换句话说,UIView本身不具备显示的功能,是它内部的层才有显示功能

 

每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)

//view.layer.delegate == view;

    

    

//----------------view的完整显示过程-----------------------------

 1. view.layer会准备一个Layer Graphics Contex(图层类型的上下文)

 2. 调用view.layer.delegate(view)的drawLayer:inContext:,并传入刚才准备好的上下文

 3. view的drawLayer:inContext:方法内部又会调用view的drawRect:方法

 4. view就可以在drawRect:方法中实现绘图代码, 所有东西最终都绘制到view.layer上面

 5. 系统再将view.layer的内容拷贝到屏幕, 于是完成了view的显示

//----------------view的完整显示过程-----------------------------

 

    coreQuatz  库不能重复添加,重复添加汇报链接错误,解决方法:重建工程:重新添加文件代码和UIStoryboardSegue

daima

 

 

 

 

    // 1.创建动画对象

    CABasicAnimation *anim = [CABasicAnimation animation];

    // 2.设置动画对象

    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画

    

    anim.keyPath = @"bounds";

    //    anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];

    anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];

    anim.duration = 2.0;

    

    /**让图层保持动画执行完毕后的状态**/

    // 动画执行完毕后不要删除动画

    anim.removedOnCompletion = NO;

    // 保持最新的状态

    anim.fillMode = kCAFillModeForwards;

    

    // 3.添加动画

    [self.layer addAnimation:anim forKey:nil];

 

block 封装函数的变化点

    

 

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);

使用给定的block 执行数组中的对象,从第一个对象执行到最后一个对象,block是应用到每一个对象的代码

    

    int stopIndex = 1;

    NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

        if ([@"王五" isEqualToString:obj] || idx == stopIndex) {

            *stop = YES;

        }

    }];

    注意,

 

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

        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{

            [self operationAction:@(i)];

        }];

        

        [self.myQueue addOperation:op];

    }

 

 

 

 

//----------------block强引用---------------------------------------------------

@property (nonatomic, strong) NSMutableArray *myBlocks;

 

#pragma mark 将代码改为调用self的方法

int(^sum)(int, int) = ^(int x, int y) {

return [self sum:x y:y];

};

[self.myBlocks addObject:sum];

#pragma mark 对象被释放时自动调用

- (void)dealloc

{

NSLog(@"DemoObj被释放");

}

循环引用的结果就是对象无法被释放!

 

上述代码:self 强应用myBlaocks  ,myBlocks 强引用sum   sum强引用self 构成强引用的循环三角形(无法释放)

 

局部变量默认都是强引用的,离开其所在的作用域之后就会被释放

 

使用__weak关键字,可以将局部变量声明为弱引用

__weak DemoObj *weakSelf = self;

在Block中引用weakSelf,则Block不会再对self做强引用

int(^sum)(int, int) = ^(int x, int y) {

return [weakSelf sum:x y:y];

};

//----------------block强引用---加上最后一句-<2>解决问题-----------------------------------------------

#warning 注释---******* 3> option被item2强引用  ??????

    item2.option = ^{

        //  判断当前设备能否发送邮件 ,不能发邮件

        if (![MFMailComposeViewController canSendMail]) return;

        

        MFMailComposeViewController *vc = [[MFMailComposeViewController alloc] init];

        

        // 设置邮件主题

        [vc setSubject:@"会议"];

        // 设置邮件内容

        [vc setMessageBody:@"今天下午开会吧" isHTML:NO];

        // 设置收件人列表

        [vc setToRecipients:@[@"643055866@qq.com"]];

        // 设置抄送人列表

        [vc setCcRecipients:@[@"1234@qq.com"]];

        // 设置密送人列表

        [vc setBccRecipients:@[@"56789@qq.com"]];

        

        // 添加附件(一张图片)

        UIImage *image = [UIImage imageNamed:@"lufy.jpeg"];

        NSData *data = UIImageJPEGRepresentation(image, 0.5);

        [vc addAttachmentData:data mimeType:@"image/jepg" fileName:@"lufy.jpeg"];

#warning 注释--- 4> option中的block强引用着当前类(形成强应用闭环)

        // 设置代理

        vc.mailComposeDelegate = self;

        // 显示控制器

        [self presentViewController:vc animated:YES completion:nil];

        

    };

#warning 注释---*******1> group(被本类强引用,里面的成员)

    NJSettingGroup *group = [[NJSettingGroup alloc] init];

    group.items = @[item0, item1, item2];

    [self.data addObject:group];

#warning 注释---*******2> items(被group强引)

    

    // 把self变成弱指针

    // __unsafe_unretained 修饰的如果对象释放了, 变量依然指向释放前的地址

    // __unsafe_unretained NJShareViewController *unRetainSelf = self;

    //  __weak 修饰的如果对象释放了, 变量自动指向nil

    // __weak NJShareViewController *unRetainSelf = self;

    

   <2> __weak typeof(self) unRetainSelf = self;

    

    __block  可以修改block的值  少用:破坏可读性,偶尔性太高,不允许修改快代码中的指针,可以修改快代码中指针的内容,

    对象有两个地址:指向对象的地址(两个),对象本省的地址(一个,不可以修改),地址中存放内容(可以修改),

    __weak  NJcontroller *weakself  = self;

    

}

//----------------block强引用---------------------------------------------------

 

    对象添加到数组会被数组强引用;[self  sum:x ,y]  self 会对sum强引用   ????强引用??

    self 中有property (nonatomic, strong) NSMutableArray *myBlocks;

    self  会强应用myBlocks

    

    sum 会强引用self

    int(^sum)(int, int) = ^(int x, int y) {

        return [self sum:x y:y];

    };

 

    [self.myBlocks addObject:sum];

 

    myblock会强引用sum  导致的循环引用

    

    

    代码网站:githup   和codeforapp  两个网站  上面有很多内容

    

//----------------block循环引用---------------------------------------------------

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

        

        [self.queue addOperationWithBlock:^{

            self  ->queue ->block  在主线程的运行循环中,队列的代码块执行完毕会销毁

            [self demoOp:@(i)];

        }];

    }

//----------------block循环引用---------------------------------------------------

 

 

快代码  准备的函数,随时被调用,预先准备好的,

    快代码实现控制器中的传值,

    1>快代码预先准备的代码块,在需要的时候执行

    2>准备一个快代码,传递给detail

    3>快代码自行时间有detail(定义快代码) 决定

    

快代码比较灵活,如果监听的事件比较多,还是使用代理比较好

    

  堆中存放对象,栈中存放地址

    

 

    ?const 的作用

    CGPathCreateMutableCopyByTransformingPath(<#CGPathRef path#>, <#const CGAffineTransform *transform#>)

    dispatch_queue_t q = dispatch_queue_create(<#const char *label#>, <#dispatch_queue_attr_t attr#>)

    const 锁定指向lable的指针,

    UIKIT_EXTERN NSString *const NSTabColumnTerminatorsAttributeName

    锁定的是NSTabColumnTerminatorsAttributeName这内容;

    //const  指针可以修改,指针所指向

 

    

    

    //----------------串行队列-----------------------------

    串行队列前面的没有执行完后面的队列无法执行

    并行队列,先同步后异步  顺序执行:

    并行队列:先异步后同步,混合执行,同步异步混合;先同步后异步,会对后面的阻塞;

    同步操作在主线程上,异步会新建线程,在并行队列中:异步会新建多个线程,在串行队列中异步只会新建一个线程

    全局队列:同步操作顺序进行,在主线程上,会阻塞后面的,异步操作无序,会新建线程,无序进行

    //----------------创建全局对列-----------------------------

    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //执行同步操作,在主线程上

    //执行异步操作,在子线程上还是会有顺序

    //---------------------------------------------

    

    //-------------------主(线程)队列--------------------------

    

#pragma mark - 主(线程)队列,保证操作在主线程上执行

    

    // 每一个应用程序都只有一个主线程

    // 为什么需要在主线程上工作呢?

    // 在iOS开发中,所有UI的更新工作,都必须在主线程上执行!

    dispatch_queue_t q = dispatch_get_main_queue();

    

    // 主线程是由工作的,而且除非将程序杀掉,否则主线程的工作永远不会结束!

    // 阻塞了!!!

    //    dispatch_sync(q, ^{

    //        NSLog(@"come here baby!");

    //    });

    

    // 异步任务,在主线程上运行,同时是保持队形的

    同步任务:不会新建线程,运行在主线程上只能在(队列在哪里,任务就在哪里)主线程上,

    异步任务:会新建线程;同步任务可以堵住异步任务

    

    同步任务会堵死程序

    主线程的任务不会结束(除非退出程序),

    全局队列不能跟踪:自己创建的队列可以跟踪

    全局队列可以指定优先级,自己创建的队列不能创建优先级

    

    主队列添加任务在主队列工作,自己创建的nsopration  自动的并行异步

    

An NSThread object controls a thread of execution. Use this class when you want to have an Objective-C method run in its own thread of execution. Threads are especially useful when you need to perform a lengthy task, but don’t want it to block the execution of the rest of the application. In particular, you can use threads to avoid blocking the main thread of the application, which handles user interface and event-related actions. Threads can also be used to divide a large job into several smaller jobs, which can lead to performance increases on multi-core computers.

一个线程对象控制一个线程的执行,当你想要一个oc 的方法运行在执行的线程上,就使用这个类,当你需要执行一个长时间的任务,线程是非常有用的,但是不要去阻塞其他应用程序的执行,特殊是:你可以使用线程避免阻塞主线程

主线程来更新界面相关的动作事件,线程可以划分一个大的任务为几个小的任务,在多核的设备中,这样可以提高性能

 

    1>NSObject  多线程方法没有自动释放池

    2>在oc,当自动释放池被释放或销毁的时候,会向自动释放池中得所有对象发送release消息

    

    //但是使用nsthread 的时候系统

    同步任务在多线程中少用,(少用)

    

    串行 异步:

    并行  异步:

    

    NSAutoreleasePool

    {

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

//            NSAutoreleasePool也可以在这里加自动释放池,这样的每次执行完毕对象会释放{

            NSString *str = @"Hello World";

            str = [str stringByAppendingFormat:@" - %d", i];

            str = [str uppercaseString];

            NSLog(@"%@", str);

//        }

        }

    }      问:以上代码存在什么样的问题?如果循环的次数非常大时,应该如何修改?

 

    

    

#pragma mark - 串行(一个接一个,排队跑步,保持队形)队列

    - (void)gcdDemo1

    {

        // 将操作放在队列中

        // 在C语言函数中,定义类型,绝大多数的结尾是_t或者ref

        // 使用串行队列,的异步任务非常非常非常有用!新建子线程是有开销的,不能无休止新建线程

        // 即可以保证效率(新建一个子线程),用能够实现并发

        // 应用案例:

        // 1> 从网络上上下载图片

        // 2> 滤镜(高光,红眼...)

        

        dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL);

        

        // 非ARC开发时,千万别忘记release

        //    dispatch_release(q);

        

        // 串行行队列的同步任务,同样会在主线程上运行

        // 提示:在开发中极少用

        // 面试中有可能会问!

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

            // 同步任务顺序执行

            dispatch_sync(q, ^{

                NSLog(@"%@ %d", [NSThread currentThread], i);

            });

        }

        

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

            // 异步任务,并发执行,但是如果在穿行队列中,仍然会依次顺序执行

            dispatch_async(q, ^{

                // [NSThread currentThread] 可以在开发中,跟踪当前线程

                // num = 1,表示主线程

                // num = 2,表示第2个子线程。。。

                NSLog(@"%@ %d", [NSThread currentThread], i);

                

            });

        }

    }

    

    NSThread 对象的作用:

    一个线程对象控制一个线程的执行,当你想要一个oc 的方法运行在执行的线程上,就使用这个类,当你需要执行一个长时间的任务,线程是非常有用的,但是不要去阻塞其他应用程序的执行,特殊是:你可以使用线程避免阻塞主线程

    主线程来更新界面相关的动作事件,线程可以划分一个大的任务为几个小的任务,这样可以提高性能

    

    互斥锁:每一次只允许一个任务执行操作

    

    

    //

    //  DemoObj.m

    //  05.单例

    //

    //  Created by apple on 14-4-23.

    //  Copyright (c) 2014年 itcast. All rights reserved.

    //

    

    #import "DemoObj.h"

    

    @implementation DemoObj

    

    static DemoObj *instance;

    //---------------------单例的写法,面试常考------------------------

    /**

     1. 重写allocWithZone,用dispatch_once实例化一个静态变量

     2. 写一个+sharedXXX方便其他类调用

     */

    

    // 在iOS中,所有对象的内存空间的分配,最终都会调用allocWithZone方法

    // 如果要做单例,需要重写此方法

    // GCD提供了一个方法,专门用来创建单例的

    + (id)allocWithZone:(struct _NSZone *)zone

    {

        static DemoObj *instance;

        

        // dispatch_once是线程安全的,onceToken默认为0

        static dispatch_once_t onceToken;

        // dispatch_once宏可以保证块代码中 i的指令只被执行一次

        dispatch_once(&onceToken, ^{

            // 在多线程环境下,永远只会被执行一次,instance只会被实例化一次

            instance = [super allocWithZone:zone];

        });

        

        return instance;

    }

    

    + (instancetype)sharedDemoObj

    {

        // 如果有两个线程同时实例化,很有可能创建出两个实例来

        //    if (!instance) {

        //        // thread 1 0x0000A

        //        // thread 2 0x0000B

        //        instance = [[self alloc] init];

        //    }

        //    // 第一个线程返回的指针已经被修改!

        //    return instance;

        return [[self alloc] init];

    }

    

    @end

    //  DemoObj.m

    //  0526_单利

    //

    //  Created by 汪刚 on 07-9-19.

    //  Copyright (c) 2007年 it.cast. All rights reserved.

    //

    

#import "DemoObj.h"

    

    @implementation DemoObj

    static DemoObj *instance

    //

    +(id)allocWithZone:(struct _NSZone *)zone

    {

        static DemoObj*instance;

        //这个

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            //这个中得代码只执行一次

            instance = [super allocWithZone:zone];

        });

        return instance;

    }

    

    +(instancetype)shareDemoObj

    {

        return [[self alloc] init];

    }

 

    //----------------------单例的写法,面试常考-----------------------

   

oc函数中参数凡是看到**  传入对象的地址

    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:/*传地址*/(NSURLResponse **)response error:(NSError **)error

 

1M主线程,每个线程对应一个栈区,子线程对应512K的栈区

    

    堆区,有系统管理和维护   包含所有应用程序共享的(包含内存,虚拟内存(磁盘内存))

    

    对象在堆中,内存没有释放(无法访问)那么对象就是内存泄露

    堆系统管理所有对象的,

    NSData  二进制

    NULL = 0;

    nil 地址指向0 的对象;调用任何方法不会报错; =空

    

//--------------------- performSelectorOnMainThread------------------------

-(void)setImagePath:(NSString *)imagePath

{

NSLog(@"%@ = \n",[NSThread currentThread]);

//1>模拟下载延时

[NSThread  sleepForTimeInterval:5.0];

//A Boolean that specifies whether [the current thread blocks until after the specified selector is performed on the receiver on the main thread].

//2>设置头像,苹果允许inbackground方法在后台更新ui线程,强烈建议不要这么做

//yes直到方法调用为yes

[self   performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:imagePath] waitUntilDone:NO];//调用的方法num =1;

 

}

 

//1>设置头像

-(void)setImage:(UIImage *)image

{

NSLog(@"%@ = setImage\n",[NSThread currentThread]);

 

//image = [UIImage imageNamed:@"头像1.png"];

self.imageView.image = image;

//根据头像自动调整大小

[self.imageView sizeToFit];

}

 

- (void)viewDidLoad

{

[super viewDidLoad];

[self.view addSubview:self.imageView];

//在后台执行这个程序

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

[self performSelectorInBackground:@selector(setImagePath:) withObject:@"头像1.png"];

}

//调用的方法Num= 1-50;

}

//--------------------- performSelectorOnMainThread------------------------

    

    

    apach演示:拖两个文件到本地服务器  打开

    再输密码

    

    界面(uitextFiled)+ UILabel

    

    2>拖线

    3>

    

NSMutableArray *arrM

    

init

    

    

    整数  NSNumber  整数对象

    

    网络数据包装

    assign  NSInteger

    @(12)

    输出为NSNumber 类型  %@   @(12)

    

    strong   NSNumber* userNum  %@

    

    

  在处理网络数据的时候,数值的属性 可以省略很多麻烦

    

    异步操作不会阻塞线程

    

    打印description  便于调试

    

 

 跟踪数组,打印数组

    自动备份;勾上;一定要掌握:switch  备份

    

    

   // copy  建立副本    为了修改属性互不影响

    

#define   kBaseUrl @"http://192.168.1.1"

    有中文的时候:url = [url string +中文转义];

    

    asi 建议需要的时候自己去自学,http 访问终结者

    非Arc

    1>第三方框架:不需要去看所有的源程序

    2>不需要熟悉所有的功能之后再使用

    

    刷新表格会重新调用数据源的方法

    

    modal  是临时的视图控制器

    横竖频还需要修改plist 里面的播放的顺序

    

    

    以shared standart  default  开头代表是单例

    

    @interface Video : NSObject

    // copy  建立副本    为了修改属性互不影响

    @property (nonatomic, copy) NSNumber *videoId;

    @property (nonatomic, copy) NSString *name;

    @property (nonatomic, copy) NSNumber *length;

    @property (nonatomic, copy) NSString *videoURL;

    @property (nonatomic, copy) NSString *imageURL;

    @property (nonatomic, copy) NSString *desc;

    @property (nonatomic, copy) NSString *teacher;

    

    - (instancetype)initWithDict:(NSDictionary *)dict;

    + (instancetype)videoWithDict:(NSDictionary *)dict;

 

    // 在处理网络数据解析的时候,数值型的属性,一定用NSNubmer,会避免很多麻烦

    @property (nonatomic, strong) NSNumber *userId;

 

    小技巧:如果在OC中看到枚举类型的起始数值不为0,说明如果传入0作为参数,意味着不会做任何附加操作

    结果就是方法运行的效率最高

    

    通常开发时,拿到数据字典,会字典转模型,因此不需要对反序列化的结果进行处理

 

    /*

     

     (下面的ok)

     void(^me)(UIImage *image) = ^(UIImage *image) {

           self.imageView.image = image;

     };

     

   (类型的时候省略block的名称)  void(^me)(UIImage *image) = ^(UIImage *image) {

     self.imageView.image = image;

     };

     

     

     

     completion(参数)调用

     

     ==

     

     ^(UIImage *image) {

     

     self.imageView.image = image;

     } 

     

     ==

     

     void (^)(UIImage *image)

     

     */

 

涉及用户隐私的  都不需要用get 方法

    不能把密码保存在本地:

    不能直接传输用户的密码:

    

    request  请求用可变的nsmuatblequequest  post  需要更改请求?

    和用户隐私相关的用post   没有隐私的时候用get   可以用浏览器辅助yong

    post 的文件不能覆盖

    post  会有大小的限制

    

     所有的网络都是异步的

    request.HTTPMethod = @"PUT";只要不是get方法  必须是可变的

 

    

    php  输入张三  zhang 的密码后,返回null null 是因为加密后,在php文件中需要更改  加密后的密码

    后面:添加psot 文件夹,系统也是这么设置的

    

    

    

    //---------------------------------------------

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task

didSendBodyData:(int64_t)bytesSent

totalBytesSent:(int64_t)totalBytesSent

totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend

    {

        float progress = (float)totalBytesSent/totalBytesExpectedToSend;

        double delayInSeconds = 1/30;

#warning 注释---???此处如果没有延时,不会重绘??  刷新频率太高???

        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));

        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

            self.progressView.progress = progress;

            

        });

        NSLog(@"progress- = %.2f\n",progress);

        //    NJProgressView *progress1 = [[NJProgressView alloc] init];

    }

    

    - (UILabel *)label

    {

        if (!_label) {

            _label = [[UILabel alloc] initWithFrame:self.bounds];

            _label.textAlignment = NSTextAlignmentCenter;

            _label.font = [UIFont systemFontOfSize:14.0];

            _label.textColor = [UIColor redColor];

            

            [self addSubview:_label];

        }

        return _label;

    }

    

    - (void)setProgress:(float)progress

    {

        _progress = progress;

        

        int value = progress * 100;

        self.label.text = [NSString stringWithFormat:@"%d%%", value];

        NSLog(@"%@", [NSThread currentThread]);

        

        // 绘制圆弧, 调用drawRect

        [self setNeedsDisplay];

    }

    

    - (void)drawRect:(CGRect)rect

    {

        // 1. context

        CGContextRef context = UIGraphicsGetCurrentContext();

        

        // 2. 给context添加路径,圆弧

        CGFloat x = self.bounds.size.width / 2.0;

        CGFloat y = self.bounds.size.height / 2.0;

        CGFloat r = MIN(x, y) - 5;

        CGFloat startA = -M_PI_2;

        CGFloat endA = startA + self.progress * 2 * M_PI;

        

        // 顺时针绘制,需要设置成false

        CGContextAddArc(context, x, y, r, startA, endA, false);

        

        // 3. 设置颜色,线宽

        CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);

        CGContextSetLineWidth(context, 3.0);

        

        // 4. 绘制

        CGContextDrawPath(context, kCGPathStroke);

    }

 

    

    //---------------------------------------------

 

 

    /** 下载是 get 方法 */

    - (IBAction)download

    {

        // 1. url

        NSURL *url = [NSURL URLWithString:@"http://localhost/123.zip"];

        

        // 2. request

        NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10.0f];

        

        // 3. sesssion

        NSURLSession *session = [NSURLSession sharedSession];

        

        // 4. 下载任务

        [[session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {

            

            // 用urlsession下载的文件,会保存到临时文件夹中

            // 如果不进行特殊的处理,就会被删除掉

            NSLog(@"%@", location.path);

            

            // 解压缩

            // 小说,下载的是zip文件,解压缩zip文件,zip不需要

            // 目标文件夹

            // Documents 只能保存应用程序本身由用户生成的文件,不能把网络下载的文件放在此文件夹中

            // Cache:重新启动不会丢失

            // Tmp:重新启动会清空

            // 偏好设置:会备份

            NSString *cacheDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];

            [SSZipArchive unzipFileAtPath:location.path toDestination:cacheDir];

        }] resume];

    }

    

    /**

     completionHandler  结束后的操作

     */

    

    文件下载从服务器下载到手机,;;可以指定下载的路径

    

    备课笔记

    

    1.  POST提交数据 application/x-www-form-urlencoded

    ================================================================================

    application/x-www-form-urlencoded在HTTP网络访问中通常用于向服务器提交用户隐私相关的信息

    

    原因如下:

    1>  使用GET方法所有参数都包含在URL中,这样用户信息会暴露在URL中,如果黑客获取到服务器访问日志文件。

    则意味着会出现用户数据泄露的问题

    2>  服务器的访问日志是黑客攻击的重点对象之一

    

    在iOS开发中,使用application/x-www-form-urlencoded提交POST请求时,程序员只需要负责包装数据体即可

    其他诸如:

    1>  Content-Type

    2>  Content-Length

    3>  数据体字符串中的百分号转义

    ...

    系统会默认处理,无需程序员做任何操作

    

    实例代码如下:

    // 1. 设置请求的HTTP方法

    request.HTTPMethod = @"POST";

    // 2. 拼接数据体字符串

    NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@", self.userNameText.text, pwd];

    // 3. 使用NSData设置HTTPBody

    request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];

    

    2.  数据安全

    ================================================================================

    在网络传输中,如果涉及用户隐私的数据,请记住以下两点:

    

    1>  任何应用程序都不能"在本地直接存储与安全相关的用户信息"

    2>  任何应用程序在于服务器传递数据时,都"不能直接传输与安全相关的用户信息"

    

    通常使用MD5对用户的密码进行加密,MD5函数具有以下特点:

    

    1>  算法不可逆,即使用散列后的MD5字符串,在知道MD5算法的前提下,仍然无法反算会初始值

    2>  长度固定,使用MD5函数处理后的字符串长度统一为32位

    3>  对于相同字符串使用MD5函数,每次的计算结果是相同的

    

    由于目前网络上有160TB的数据库,记录已经破解的,MD5加密字符串

    为了保证用户数据的安全,在使用MD5对用户密码进行处理时,可以为密码加点"盐"

    

    NSString *saltStr = [NSString stringWithFormat:@"%@%@", pwd, kSaltStr];

    return [saltStr md5String];

    

    3.  POST上传 multipart/form-data

    ================================================================================

    multipart/form-data是目前非常流行的向网络服务器上传文件的一种方式,具有以下几个特点:

    

    1>  国内的绝大多数网站都采用这种方式上传文件,网络上要上传用户头像,通常都使用此种方式

    2>  会限制上传文件的大小一般是2M或者更小

    3>  POST上传的文件在服务器上不能重名,如果指定的文件名重复,则无法上传

    

    要在iOS中实现文件上传,需要拼接一个NSData,具体个数如下:

    

# 头部字符串

    --'本次上传标示字符串' \n

    Content-Disposition: form-data; name="服务端字段"; filename="上传文件名" \n

    Content-Type: '上传文件MIMEType' \n\n

    

# 上传文件的二进制数据

    

# 底部字符串

    --本次上传标示字符串 \n

    Content-Disposition: form-data; name="submit" \n\n

    

    Submit \n

    --'本次上传标示字符串'-- \n

    

    除此之外,还需设置网络请求的'Content-Type'和'Content-Length'

    // Content-Type

    NSString *typeStr = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", randomIDStr];

    [requestM setValue:typeStr forHTTPHeaderField:@"Content-Type"];

    // Content-Length

    NSString *lengthStr = [NSString stringWithFormat:@"%ld", (long)[dataM length]];

    [requestM setValue:lengthStr forHTTPHeaderField:@"Content-Length"];

    

    网络请求准备就绪之后,直接使用NSURLConnection的异步方法即可上传文件。

    

    4.  POST上传 文件名

    ================================================================================

    为了解决POST上传文件名不能重复的问题,通常采用时间戳作为上传文件的文件名,示例代码如下:

    

    // 日期的格式化类

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

    // 设置日期格式[年月日时分秒]

    formatter.dateFormat = @"yyyyMMddHHmmss";

    // 使用当前系统时间作为文件名

    NSString *fileName = [formatter stringFromDate:[NSDate date]];

    

    5.  NSURLSession

    ================================================================================

    1>  NSURLSession是iOS7中新的网络接口,与NSURLConnection是并列的

    2>  NSURLSession是线程安全的思路

    3>  NSURLSession提供了后台上传下载的支持

    

    使用NSURLSession的步骤

    

    1>  实例化NSURLSession对象,如果不使用代理,可以使用系统提供全局网络回话单例

    [NSURLSession sharedSession]

    

    2>  由session发起任务

    (1) 数据任务    NSURLSessionDataTask

    (2) 上传任务    NSURLSessionUploadTask

    (3) 下载任务    NSURLSessionDownloadTask

    

    3>  注意:所有任务默认都是挂起的,需要调用resume方法,启动任务

    

    //---------------------------------------------

    put 上传一般传到,weddav 服务器中,可以传的数据比较大

    文件下载:从指定的服务器中下载数据  默认会存在 tmp 文件夹下面,(这个文件夹中的)

    //---------------------------------------------

 

    responseSerializer  序列化

    

    子类中的找不到所需要功能,类型的时候,到父类中得去找有没有需要的功能;

    先去头文件中框架  看看简介

    

    xml解析器 设置代理  六个方法解析 xml

    

  monitor  [  visible

 

 

青花瓷  在  工作中抓数据青花瓷安装

    UIScrollView 的bounds  和其contentoffset 是一样的

#warning 注释---微博:笔记

 

1>服务器

    2>项目组:

    1>开发组(iOS Android)

    2>服务器开发组

    3>产品需求组

    4>测试组

    5>美工组

    

    去大公司,积累规范

        1>

    项目文档

            1>需求文档-产品经理,怎么写

            2>接口文档-服务器

            3>开发文档 - 开发进度

            4>产品文档-  类似商品计划书

            5>原型图 - 类似需求文档 (index.html   首页)

            

    项目架构:

            1>UI界面层

            2>业务层

            3>网络处理层

            4>工具层

            5>网络处理层

    分配任务

            1>功能和模块分

            2>项目的架构(各个UI,网络,不同的人)

            3>混合分

    新浪开放了部分数据,开放了部分数据接口

    1>下载安装包  获取里面的资源

            

   

    launchimage 里面所有的设备都要有图标,修改json  参见新浪微博的图标json

            1>project  Hide during  application launch(加载的时候隐藏状态栏,不要时加载完)

            2>完成加载显示

            玻璃效果,右边的

            删storyBord  ,更改main?? 创建窗口

            重写控制器在initNib的方法,init会调用这个 %100会调用initWithNib的方法

            随机色

            适配两张图片   6,7 分别

            重构 代码:相同的提取 不同的

            

            

     默认渲染蓝色,所以设置渲染模式,参见0606-6,

            

           7.6适配

            适配 判断很复杂(每个)

            在初花化中判断:(高级一点)

            image分类:分类的方法会覆盖系统的方法,当同名的时候

            pch  中导入所有的文件

            

            对系统的项目包装;

            删插件;改插件   改plist

            

            友盟   GitHub   codeForApp

            git 写-

            uiview 加分类;扩充功能

            分类中加方法;

            分类中加属性,只会生成get  set 声明,不会生成 方法

            

 懒加载的好处1>代码独立   2>为空就创建   3>提高性能

            只需要创建一次的时候,用懒加载

            

            要想为什么这么写???多思考

            

#warning 注释---此处删掉storyBoard  就需要创建windown 并且显示,让程序

 

    

            0924:导航栏一行相当于两行:child.title  设置上面和下面

    

            手动切换比较快

            

            系统不好用得时候 ,自定义TabBar  SearchBar

#warning 注释---技巧

            子类中没有的属性去父类中找

            

            init 默认的宽高 00

            initwithImage  宽高是图片的宽高

 

#warning 注释---此处里面不能设置frame

            - (id)initWithFrame:(CGRect)frame

在layoutSubview 里面设置frame

        当图片在右 文字在左的时候需要自定义button

 

            让一个View  填充整个图片  思路:重写drawRect  自定义Viw

 

            弹出view 14:12 ????为什么加载window上面

        私有api  不能使用  可以用父类

            

            手势识别器  如果为空,

            

 桥接是  corefoundation  和foundatio之间的转换

            3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  

   self.plusButton.bounds = (CGRect){CGPointZero, plusButtonSize};

    上面这种写法,返回值必须强转CGRect

      类方法中只能调用类方法

         [navBar setBackgroundImage:[UIImage imageWithName:@"navigationbar_background"] forBarMetrics:UIBarMetricsDefault];

//            默认用一条线平铺

            imageWithName:@"searchbar_textfield_search_icon"];

    // 通过initWithImage:创建的UIImageView, UIImageView的尺寸就是图片的尺寸

  可以自定义按钮的尺寸和 文字和图片的大小

    - (CGRect)imageRectForContentRect:(CGRect)contentRect

    {

        CGFloat imageY = 0;

        CGFloat imageW = IWTitleButtonImageW;

        CGFloat imageX = self.width - imageW;

        CGFloat imageH = self.height;

        return CGRectMake(imageX, imageY, imageW, imageH);

    }

    

    - (CGRect)titleRectForContentRect:(CGRect)contentRect

    {

        CGFloat titleY = 0;

        CGFloat titleX = 0;

        CGFloat titleW = self.width - IWTitleButtonImageW;

        CGFloat titleH = self.height;

        return CGRectMake(titleX, titleY, titleW, titleH);

    }

 

    

            微博思路:

            1> 设置窗口的根控制器

            2>   1.创建一个新的tabbar s

                 2.移除系统自带的tabbar

            3> 创建并添加子控制器   初始化自己的所有子控制器,每个子控制器UITableViewController,添加到UITabBarController 的时候就具有tabar

            的属性,可以设置标题,图像;

                3.1>初始化每个的时候在初始化具体的控制器

            

             4>系统自带的tabBar  只有四个按钮(比较整齐),没有添加大加号,所以自定义tabBar,

            5>

 

UIButton

    

    @property(nonatomic)          UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR; // default is UIEdgeInsetsZero

    @property(nonatomic)          UIEdgeInsets titleEdgeInsets;                // default is UIEdgeInsetsZero

    @property(nonatomic)          BOOL         reversesTitleShadowWhenHighlighted; // default is NO. if YES, shadow reverses to shift between engrave and emboss appearance

    @property(nonatomic)          UIEdgeInsets imageEdgeInsets;

   设置button  image title 的四周多大的范围不能用,内部内容会压缩

 

 

    切换控制器   :

    1>modal  会保住之前的控制器

    2>push  需要导航控制器(需要导航,缺点,push后的不能销毁)

    3>切换根控制器

    1>2>根据动画效果决定

    

  对象无指针会销毁

    

default-568h.@2x.png  ;lanuch

     里面才会自动加载

    @2x 点击rentnia  拖动  否则unsign  不能用

    

    

    隐私删Cookie

    

    oauth授权

当使用的是  数字的时候,使用  对数字对象便于用户开发

    /**

     *  用户的唯一标示

     */

    @property (nonatomic, copy) NSNumber *uid;

    新建不同的方法类  可以保证不同的值在不同的文件中传输

 

    字符串截取

    - (void)setSource:(NSString *)source

    {

        int loc = [source rangeOfString:@">"].location + 1;

        int length = [source rangeOfString:@"</"].location - loc;

        source = [source substringWithRange:NSMakeRange(loc, length)];

        

        _source = [NSString stringWithFormat:@"来自%@", source];

    }

    新浪返回的格式是美国的时间格式,   loacl  应该写美国的时间;

    真机调试需要加fmt.local  = [[nsloclal alloc ]init];

    否则时间不显示

    

    无法测试环境,比如去年的时间, 可以写死创造测试条件;

    Next

    Overview

    

    The UIWindow class defines an object known as a window that manages and coordinates the views an app displays on a device screen. Unless an app can display content on an external device screen, an app has only one window.

    

    The two principal functions of a window are to provide an area for displaying its views and to distribute events to the views. To change the content your app displays, you can change the window’s root view; you don’t create a new window. A window belongs to a level—typically, UIWindowLevelNormal—that represents where it sits on the z-axis relative to other windows. For example, a system alert window appears above normal app windows.

    

Note: When you use storyboards and the Xcode app templates to create an app, a window is created for you. If you choose to create a window in Interface Builder, be sure to select the Full Screen at Launch option in the Attributes inspector so that the window is sized appropriately for the current device. Because a window doesn’t receive touch events outside of its bounds and views aren’t clipped to the window’s bounds by default, an improperly sized window might not be able to deliver touch events to all its views.

    For more information about how to use windows, see Multiple Display Programming Guide for iOS.

        

        Tasks

        

        Configuring Windows

        windowLevel  property

        screen  property

        rootViewController  property

        Making Windows Key

        keyWindow  property

        – makeKeyAndVisible

        – becomeKeyWindow

        – makeKeyWindow

        – resignKeyWindow

        Converting Coordinates

        – convertPoint:toWindow:

        – convertPoint:fromWindow:

        – convertRect:toWindow:

        – convertRect:fromWindow:

        Sending Events   – sendEvent:

        Properties

        

keyWindow(是否是keyWindo )

@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow

 

Discussion

If YES, the receiver is the key window for the application; otherwise, NO.

//主window  接受键盘,和其他非触摸相关的事件,同一时间只能有一个keywindow

 

rootViewController

The root view controller for the window.

 

window 的根控制器,提供window的内容view 指定根控制器 让控制器的view 作为window的contenView  添加根控制器以前的控制器

会移除,新的控制器的view 会被安装,默认的属性,,[pp]

@property(nonatomic, retain) UIViewController *rootViewController

 

 

The default value of this property is nil.

 

 

  #warning 注释---

    // 当前时间

    NSDate *now = [NSDate date];

    // 比较当前时间 和 账号的过期时间

    if ([account.expires_time compare:now] == NSOrderedAscending) { // 过期

        return nil; // 直接返回nil

    }

    

    return account;

    

    

    图文混排,coreText  使用第三方框架

    #pragma mark-

    字符串退换  很强大

    

    //---------------------------------------------

    只要用到令外的东西  ,都需要导入该头文件(即使已经导入了父的头文件)

    //---------------------------------------------

    

    [UIColor  colorwithimage :]= color

    

    一个控件移动需要回去的时候  使用CATransform3D

    [NSTimer  sched

     

     

     kvc   key Value  coding

     kvo  key value  observe  监听对象的属性改变

     NSDictionary *dict = @{@(1):@(2),@(1):@(2)};

     

     

    nsnumber  转化为字符串 description

 

     如何保证程序在后台运行

       //---------------------------------------------

#warning 注释---set方法没保存  后面的图片出不来

    // 还有需要调用父类的方法,layoutsubViews///

 

    //---------------------------------------------

    

     initWithImage :设置的图片默认不能交互,自动调整frame,就是图片的大小

     

     

     点击按钮 :  touchupinside

     textField  单行

                不能滚动

                 有提示文字

     textview   多行输入,能滚动

                 没有提示文字

     

 

     //添加label到导航栏的下面

     [self.navigationController.view  insertSubview:lable belowSubview:self.navigationController.navigationBar];

     

     copy 以后不相互影响

     

    代理只能设一个  通知可以多个

     

     一条线平铺: 平铺的方法

     // 1.设置背景

     self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithName:@"compose_toolbar_background"]];

 

     // 3.监听键盘的通知

     位置改变的通知UIKeyboardWillChangeFrameNotification  等于下面两个通知

     

     [IWNotificationCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

     [IWNotificationCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

     以前

     

对象转结构体

        CGRect keyboardF = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];

     //textView 垂直方向上永远可以拖拽

     textView.alwaysBounceVertical = YES;

 

 

     

     监听scrollView  使用代理,键盘使用通知监听

     弹出键盘

     [self.textView becomeFirstResponder];

 

     

     取字典的value

 info[UIImagePickerControllerOriginalImage]

 

 

 

     // 发送多张图片用同一个name即可(同一个请求参数名字,服务器利用数组接收即可)

     [formData appendPartWithFileData:data name:@"pic" fileName:@"" mimeType:@"image/jpeg"];

 

     }

 

 

     //-------------------不能点击--------------------------

     父控件没有frame 子控件还会显示的,只是父控件不能接受点击事件,

    父控件设置背景色不可见,子控件就不能点击

        //---------------------------------------------

 

    // 定时发送请求给服务器(获得未读数)

       NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(getUnreadCount) userInfo:nil repeats:YES];//定时发送任务,

    //    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];//让执行其他任务的时候定时器(比如拖拽的时候,还能给定时器发送请求);

    

    

    init  内部调用 initWithNIbname(不用调父类)

     init 内部也调用 initwithname (不用调父类)

     

     模型一般继承NSObject   或者自定义的父类

     

   backGroundView  的优先级高于backGroundColor 的优先级

     

    重写frame 方法  修改cell   系统的东西改了   重写系统的方法

     

     

     hilightTextColor  高亮时文本的颜色

     

     微博第八天  穿透

     1429????

     

    配两下  配两下 就可以完成

     

     

     

     软件内存的怎么样??

     

     静态分析  有无潜在的的内存泄露

     

     动态分析: 分析

     

    发布  用safir  必须用这个

     

     

     

     

     

     nscoding :archives

     

存对象

     偏好:键值 (bool  key)

     plist :字典

     

     (以上都是小数据)

 

     

     sqlite3  跨平台

     core data  sqlite3是sqlite3的oc 形式

     

     sqlite3 轻型  几百kb 速度比mysqql  postSql  速度更快

     

     数据库

     数据结构存储数据的仓库

     有一定的格式

     dataBase

     关系型数据库

     对象型数据库

     

     常用的关系型数据库

     

     pc端 :Oracle

     嵌入式/移动客户端  SQlite

     

     数据库以表为单位

     数据库有多少张表

     表(列 -字段):存储一种数据

     5条数据 = 5条记录

     

     创建表 - 字段(列,属性) - 记录(行,record );

     navicat - .app  -sn(破解)获取  - 退出app

     blog 二进制

     

     存数据必须得有主键

     主键  增加主键约束  每个表必须有一个主键  标记记录,保持唯一

     一个主键 可以是一个或者两个字段组成主键

     主键必须保持唯一性

     

     移动开发搞一个一个字段的主键就行

     主键必须integer  才行

     key勾选代表是主键  主键不能为空,两个空 不保证唯一性

     

     写数据必须添加主键

     real 浮点型

     数据库以文件存在,永久存储

     

     

     

     auto incre

     sql 语句增加记录

     sql = structure  query language

     

     sql 是数据库语句,关系型数据定义的语言

     sql 语言易学易用

     

   数据库的  增删改查= CRUD

     sql 语句的特点:1>不区分大小写

     2> 分号结尾

     3> 关键字

     4>不能用关键字 标示变量

     5>ddl data defination language

     6>创建删表

     DMl data manipunaiton language

     insert delete update

     

     数据查询语句

     DQL     query

     

     select  查数据 (最常用的数据)

     drop 删数据

     

    创表

     create Table

     

     沙盒 nsserchPath  (doc library);

     

     mainbundle (app 的路径);

     

     

     

     - (IBAction)select {

         // 1.查询数据, 获得查询结果集

         FMResultSet *set = [self.db executeQuery:@"select * from t_student where name like ?;", @"%jay-5%"];

  #warning 注释---@"%jay-5%"  与数据库中写判断   加两个% 号不同  字符串拼接, %% 是转义子字符

         // 2.从结果集里面取出数据

         while ([set next]) {

             // 取出当期指向的那行数据

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

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

             

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

         }

     }

     

     

     

     

     .keyValues write14:31直接写入plist

     

     

     

     

     NSBundle 和沙盒 的区别???

     

     

     

     

     set

     

     copy 在block中是强引用

     网络多线程,最后一天微博多线程中的循环引用

     block 中只要用到外面东西就使用弱指针

     16:04强引用

     

     注释注释

    注释paihang

     

//     看公司代码技巧:

     修改之前备份

     名字搜不到:有可能是图片,网络数据是搜不到的;

     代码备份

     4>按钮可能是图片

     5>搜不到 就搜附近的名字

     1>注释+加搜  (主搜  + 副搜)

     2>注释:就知道做什么:

     3>直接加return 就可以知道后面的代码做什么的?

     6>名字= 组合搜

     7>中文标签是重点搜得对象

     8>控制器清空:nil

     9>一般先找viewdidload

     10>结构做笔记,熟悉公司代码的结构

     11>一层层的找控制器,就会熟悉

     12>不删除的设置背景色也可以;

     13>改东西不能一行行找

     

     面试题:c++ xmpp 讲完新浪博客 360 17.5k                     14*15

     增加的项目:多整项目,

     

     

     AFN 返回的字典数组,不能直接写入plist 因为里面有空格  逗号,等,需要用keyValues 杰哥写的字典专,再数组转模型

     

     模型再转数组的方法,再writeTofile 的方法写入plist

     

     模型存数据是把数据保存在模型的属性里面

     

     

     // 准备了一个块代码,传递给detail

     // 块代码的具体执行时间由detail决定  str 代表接受一个形参

     detail.saveBlock = ^ (NSString *str) {

         self.label.text = str;

     };

     

     //    [_delgate save:self.textField.text];

     if (self.saveBlock) {

         self.saveBlock(self.textField.text); 具体的执行由这行来执行,self.textField.text是传入的参数

     }

     

     做分享的网站:友盟,分享 光速推送

     

     

     横竖屏突破:田字格里面做横竖屏适配;

     

     长度不一样 不能所有的都勾上;

     

     让导航控制器弹出新的控制器,  再present

     创建控制器:显示的时候,宽度,永远是768;高度随屏幕

     设置弹出模态的方式;全屏中间,

     

     显示蒙版还可以点击;

     

     屏模式配  一个个的往里拖

     

     启动图片 一个个的修改json

     不适用Autolayout

     

     0622:14:15自动取色

     

     横竖屏  水平自动居中: 调整田字

     

     out of date 将自己的代码和服务器的代码进行比对

     

     svn  拷贝  修改  合并

     

        cvs   锁定  修改  解锁

     快速提交代码//

     五点钟下班,四点钟提交代码

    svn 会out of date

     

     svn  sp2  service pake 3

    直接下一步

     直接下一步,

     

     版本控制:

     

     tags 重大版本的备份

     branches 分支目录;

     

     initWithImage 默认就用宽高,

     

     UIImageView *iv = [UIImageView alloc ]initWithImage

     

     

     

     

     实际上是蓝牙链接

     peer to peer 对等 对端链接,

     

     

     监听图片点击,实现图片点击

     

     如何喧染图片;

     

     

     

     

     block  指向结构体指针

     block  回调,代码 等待被调用,当参数,也可以接受参数;

     

     __block int a  在block 中可以修改a

      是指针传递

     copy 对应一次release

     copy  将对象放在堆里面

     

     

     

     

     1.微信如何搜索附近人

     2.模糊搜索和精确搜索

     3.即时通讯的UI布局,要是你做你会用多少个cell

     4.有没有直播经验

     5.最近的ipv6上架的问题 以及了解ipv6是什么

     6.消息机制了解么?你用它做过什么!

     7.iOS如何优化

     8.instuments用过哪些工具,如何测试核心动画性能

     9.沙盒机制

     10.ffmpeg,opengl了解嘛

     11.如何收集APP异常信息(比如:崩溃、闪退等)

     12.离屏渲染了解么,了解的话说一下你一般是从哪几方面操作的

     13.了解GCD的信号量机制么!能谈谈你对它的理解么!

     14.聊下RAC和MVVM,你对它的看法

     15.block底层实现

     16.响应链底的理解

     17.KVC和KVO

     18.lldb(gdb)常用的调试命令

     19.热更新

     20.GCD实现原理

     

     

     

     

     

     

     

@interface CZPlaySoundTool ()

 

//@property (nonatomic, strong) NSMutableDictionary *soundIDs;

 

@end

 

static NSMutableDictionary *_soundIDs;

 

@implementation CZPlaySoundTool

 

// 两个方法都会调用一次

// 真正使用这个类的时候会调用

+ (void)initialize

{

    _soundIDs = [NSMutableDictionary dictionary];

}

 

// 加载类的时候就会调用

//+ (void)load

//{

//

//

//}

 

 

+ (void)playSoundWithName:(NSString *)name

{

 

    //1.根据name 取字典找soundID

    

    SystemSoundID soundID = [_soundIDs[name] intValue];

    

    //2.判断soundID

    //获取对应的音效文件

    //保存到字典

    

    if (soundID == 0) {

        // 1.获取音效文件

        

        NSString *path = [[NSBundle mainBundle]pathForResource:name ofType:nil];

        NSURL *url = [NSURL fileURLWithPath:path];

        

        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);

        

        [_soundIDs setObject:@(soundID) forKey:name];

        

    }

    

    //3.播放

    

    AudioServicesPlaySystemSound(soundID);

    

 

}

     

     

     

     

     

     

     

     

     

     

     

 

posted on 2017-01-09 22:09  1018475062  阅读(248)  评论(0编辑  收藏  举报