框架介紹
- QuartzCore:核心動(dòng)畫框架宝恶,用來做游戲的
- Mapkit:地圖框架符隙,打車軟件常用
- CoreLocation:核心定位,QQ說說垫毙,外賣軟件
代碼倉庫
存儲(chǔ)不同版本應(yīng)用程序代碼霹疫,用于對比修改了那些地方,當(dāng)新的代碼出現(xiàn)問題综芥,可以回退到上一個(gè)版本丽蝎。包含svn/git兩種
方法、屬性與對象關(guān)系
- 一個(gè)按鈕可以連接多個(gè)方法膀藐,一個(gè)對象連接多個(gè)屬性是沒有必要的屠阻,只需要連接一個(gè)屬性即可
- 判斷一個(gè)對象是否能夠連線方法,需要看該對象的類是否繼承于UIControl或者右鍵該對象看他是否包含sent events單詞
- NSSelectorFromString(NSString * _Nonnull aSelectorName):用于將字符串轉(zhuǎn)化成方法
- 只要方法名帶有file的额各,都是傳全路徑
- 如何抽方法
- 先把相同的代碼抽到方法中,不要設(shè)置方法名和參數(shù)
- 把要變化的東西換成變量,然后編譯,把報(bào)錯(cuò)的設(shè)置為方法的參數(shù)
-
接口方法
Snip20170122_48.png
控件
- 孫子控件不是子控件国觉,也就是說子控件的子控件不是我的子控件
- 只要控件有父控件,就一定能夠從父控件中移除
-
控制器的view默認(rèn)包含屏幕上下20像素高度的子控件虾啦,可以通過取消勾選去除子控件麻诀,如下圖
Snip20160103_41.png
"<_UILayoutGuide: 0x7fd0d4603820; frame = (0 0; 0 0); hidden = YES; layer = <CALayer: 0x60800003c040>>":
- 每個(gè)控件都是個(gè)容器,能容納其他控件
Tag
- tag:控件的ID傲醉,父控件可以通過tag來找到對應(yīng)子控件
- 根據(jù)一個(gè)tag標(biāo)識找出對應(yīng)的控件(一般指子控件)
-(UIView *)viewWithTag:(NSInteger)tag;
- 盡量少使用tag,原因如下:
- tag的效率非常差
- tag使用多了容易亂
-
tag執(zhí)行偽代碼如下圖:
Snip20160103_46.png
位置和尺寸
- bounds:通過bounds改變尺寸蝇闭,在iOS9以后,中心點(diǎn)不變向四周延伸
- 結(jié)構(gòu)體是值傳遞硬毕,不是地址傳遞
UIViewController的使用
- 作用:負(fù)責(zé)處理軟件界面的各種事件,并負(fù)責(zé)軟件界面的創(chuàng)建和銷毀
- 注意:每一個(gè)控制器都會(huì)專門管理一個(gè)軟件界面
- 每一個(gè)控制器(UIViewController)內(nèi)部都有個(gè)默認(rèn)的UIView屬性
UIImageView
-
判斷圖片控件是否在執(zhí)行動(dòng)畫
Snip20170119_67.png -
通過ARGB設(shè)置圖片的背景色
Snip20170119_71.png -
沙盒路徑
Snip20170119_61.png - animationRepeatCount:動(dòng)畫的播放次數(shù)(默認(rèn)是0呻引,代表無限播放
- 其實(shí)UIImageView、UILabel也可以通過手勢識別器來監(jiān)聽
UIButton
- highlighted(高亮狀態(tài))
- 按鈕被按下去的時(shí)候(手指還未松開)
- 為了保證高亮狀態(tài)下的圖片正常顯示昭殉,必須設(shè)置按鈕的type為custom
- UIButtonTypeCustom:無類型苞七,按鈕的內(nèi)容需要自定義
- 設(shè)置按鈕的文字字體(需要拿到按鈕內(nèi)部的label來設(shè)置)
btn.titleLabel.font =[UIFont systemFontOfSize:13];
- 獲得按鈕的文字
-(NSString *)titleForState:(UIControlState)state;
- 獲得按鈕的文字顏色
- (UIColor *)titleColorForState:(UIControlState)state;
- 獲得按鈕內(nèi)部的小圖片
- (UIImage *)imageForState:(UIControlState)state;
- 獲得按鈕的背景圖片
- (UIImage *)backgroundImageForState:(UIControlState)state;
* 直接通過addTarget...方法監(jiān)聽點(diǎn)擊
![Snip20170121_21.png](http://upload-images.jianshu.io/upload_images/1609505-ce999b319c1622ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 創(chuàng)建UIButton
![Snip20170121_18.png](http://upload-images.jianshu.io/upload_images/1609505-1293f5b01cf3773f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 設(shè)置按鈕字體偏移量
![Snip20170121_19.png](http://upload-images.jianshu.io/upload_images/1609505-d7209fdaad2cfbd6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#九宮格
![Snip20170121_29.png](http://upload-images.jianshu.io/upload_images/1609505-0c3de0d9110949de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_22.png](http://upload-images.jianshu.io/upload_images/1609505-4f12459c998c4405.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_23.png](http://upload-images.jianshu.io/upload_images/1609505-3d4cf47e1fc6e09a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#UILabel
* numberOfLines:文字行數(shù)
* lineBreakMode:換行模式
* 要想讓UILabel自動(dòng)換行藐守,設(shè)置Lines為0即可
#模型
* 所謂模型挪丢,其實(shí)就是數(shù)據(jù)模型蹂风,專門用來存放數(shù)據(jù)的對象
#手機(jī)尺寸
![尺寸.jpeg](http://upload-images.jianshu.io/upload_images/1609505-10c69a4fc36feb62.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#view的封裝
* 如果一個(gè)view內(nèi)部的子控件比較多,一般會(huì)考慮自定義一個(gè)view乾蓬,把它內(nèi)部子控件的創(chuàng)建屏蔽起來惠啄,不讓外界關(guān)心
* 外界可以傳入對應(yīng)的模型數(shù)據(jù)給view,view拿到模型數(shù)據(jù)后給內(nèi)部的子控件設(shè)置對應(yīng)的數(shù)據(jù)
* 代碼-自定義封裝控件的基本步驟:
* 在initWithFrame:方法中添加子控件任内,初始化子控件撵渡,提供便利構(gòu)造方法
* 在layoutSubviews方法中設(shè)置子控件的frame(一定要調(diào)用super的layoutSubviews)
* 給子控件設(shè)置數(shù)據(jù),對外增加模型對象屬性死嗦,在模型屬性set方法中設(shè)置數(shù)據(jù)到子控件上
* xIb自定義封裝控件的基本步驟:
* 新建自定義控件類
![Snip20170120_6.png](http://upload-images.jianshu.io/upload_images/1609505-18f476c7aaf84fc8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 新建xib文件(文件名建議和view的類名一致)
![Snip20170120_1.png](http://upload-images.jianshu.io/upload_images/1609505-e0553de9e76eb509.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![0001.jpg](http://upload-images.jianshu.io/upload_images/1609505-254bc3a5f19b6b04.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 修改xib中view的類名
![Snip20170120_2.png](http://upload-images.jianshu.io/upload_images/1609505-40a82d63b337faa8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 封裝xib的加載過程
![Snip20170120_3.png](http://upload-images.jianshu.io/upload_images/1609505-27cbf2b37c9cf45f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170120_4.png](http://upload-images.jianshu.io/upload_images/1609505-385e141a3ee1aad7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 增加模型屬性趋距,在模型屬性set方法中設(shè)置數(shù)據(jù)到子控件上
* Xib是輕量級的,用來描述局部的UI界面
* Xib的加載
* 方法1
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]
* 方法2
UINib *nib = [UINib nibWithNibName:@"xib文件名" bundle:nil];
NSArray *views = [nib instantiateWithOwner:nil options:nil];
* Storyboard是重量級的越除,用來描述整個(gè)軟件的多個(gè)界面节腐,并且能展示多個(gè)界面之間的跳轉(zhuǎn)關(guān)系
* 一個(gè)控件有2種創(chuàng)建方式
* 通過代碼創(chuàng)建
* 初始化時(shí)一定會(huì)調(diào)用initWithFrame:方法
* 通過xib\storyboard創(chuàng)建
* 初始化時(shí)不會(huì)調(diào)用initWithFrame:方法,只會(huì)調(diào)用initWithCoder:方法
* 初始化完畢后會(huì)調(diào)用awakeFromNib方法
* 有時(shí)候希望在控件初始化時(shí)做一些初始化操作摘盆,比如添加子控件翼雀、設(shè)置基本屬性
* 這時(shí)需要根據(jù)控件的創(chuàng)建方式,來選擇在initWithFrame:孩擂、initWithCoder:狼渊、awakeFromNib的哪個(gè)方法中操作
#顏色認(rèn)知
![Snip20170121_7.png](http://upload-images.jianshu.io/upload_images/1609505-1b471c932e2dbfdd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_8.png](http://upload-images.jianshu.io/upload_images/1609505-2214608c98e22a6e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_9.png](http://upload-images.jianshu.io/upload_images/1609505-5527a3bbd74df85e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_10.png](http://upload-images.jianshu.io/upload_images/1609505-13a9c76165598f4e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_11.png](http://upload-images.jianshu.io/upload_images/1609505-a4d22ad05169fadb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_13.png](http://upload-images.jianshu.io/upload_images/1609505-d598dc2b2dc1d91d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_14.png](http://upload-images.jianshu.io/upload_images/1609505-6c8597bbb0c294bb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170121_16.png](http://upload-images.jianshu.io/upload_images/1609505-1b8d26a8374449bd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#Autolayout
* 屏幕
* 屏幕是由無數(shù)個(gè)點(diǎn)組成的,點(diǎn)又是由像素組成的
* 非retina屏幕:1個(gè)點(diǎn)由1個(gè)像素組成
* 0retina屏幕:1個(gè)點(diǎn)由4個(gè)像素組成
* Autolayout的警告和錯(cuò)誤
* 警告
* 控件的frame不匹配所添加的約束
* 比如約束控件的寬度為100, 而控件現(xiàn)在的寬度是110
* 錯(cuò)誤
- 缺乏必要的約束
* 比如只約束了寬度和高度, 沒有約束具體的位置
* 兩個(gè)約束沖突
* 比如1個(gè)約束控件的寬度為100, 1個(gè)約束控件的寬度為110
* 代碼實(shí)現(xiàn)Autolayout的注意點(diǎn)
* 要先禁止autoresizing功能类垦,設(shè)置view的下面屬性為NO
view.translatesAutoresizingMaskIntoConstraints = NO;
* 不用再給view設(shè)置frame
* 創(chuàng)建約束對象的常用方法
* view1 :要約束的控件
* attr1 :約束的類型(做怎樣的約束)
* relation :與參照控件之間的關(guān)系
* view2 :參照的控件
* attr2 :約束的類型(做怎樣的約束)
* multiplier :乘數(shù)
* c :常量
+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
* 添加約束的規(guī)則
* 對于兩個(gè)同層級view之間的約束關(guān)系狈邑,添加到它們的父view上
![12.png](http://upload-images.jianshu.io/upload_images/1609505-13e7e8547ea796cd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 對于兩個(gè)不同層級view之間的約束關(guān)系,添加到他們最近的共同父view上
![23.png](http://upload-images.jianshu.io/upload_images/1609505-8d65c0ec02bc8924.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* 對于有層次關(guān)系的兩個(gè)view之間的約束關(guān)系蚤认,添加到層次較高的父view上
![3333.png](http://upload-images.jianshu.io/upload_images/1609505-a378eaacd52820d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* VFL示例
- canelButton寬72米苹,acceptButton寬50,它們之間間距12
- H:[cancelButton(72)]-12-[acceptButton(50)]
- wideView寬度大于等于60point烙懦,該約束條件優(yōu)先級為700(優(yōu)先級最大值為1000驱入,優(yōu)先級越高的約束越先被滿足)
- H:[wideView(>=60@700)]
- 豎直方向上,先有一個(gè)redBox氯析,其下方緊接一個(gè)高度等于redBox高度的yellowBox
- V:[redBox][yellowBox(==redBox)]
- 水平方向上亏较,F(xiàn)ind距離父view左邊緣默認(rèn)間隔寬度,之后是FindNext距離Find間隔默認(rèn)寬度掩缓;再之后是寬度不小于20的FindField雪情,它和FindNext以及父view右邊緣的間距都是默認(rèn)寬度。(豎線“|” 表示superview的邊緣)
- H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
* 使用VFL來創(chuàng)建約束數(shù)組
* format :VFL語句
* opts :約束類型
* metrics :VFL語句中用到的具體數(shù)值
* views :VFL語句中用到的控件
* 創(chuàng)建一個(gè)字典(內(nèi)部包含VFL語句中用到的控件)的快捷宏定義
- (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
NSDictionaryOfVariableBindings(...)
* 基于Autolayout的動(dòng)畫
- 在修改了約束之后你辣,只要執(zhí)行下面代碼巡通,就能做動(dòng)畫效果
[UIView animateWithDuration:1.0 animations:^{
[添加了約束的view的父控件 layoutIfNeeded];
}];
* Masonry
- mas\_equalTo和equalTo
* 默認(rèn)情況下
* mas\_equalTo有自動(dòng)包裝功能尘执,比如自動(dòng)將20包裝為@20
* equalTo沒有自動(dòng)包裝功能
* 如果添加了下面的宏,那么mas\_equalTo和equalTo就沒有區(qū)別
#define MAS_SHORTHAND_GLOBALS
// 注意:這個(gè)宏一定要添加到#import "Masonry.h"前面
- mas\_width和width
* 默認(rèn)情況下
* width是make對象的一個(gè)屬性宴凉,用來添加寬度約束用的誊锭,表示對寬度進(jìn)行約束
- mas\_width是一個(gè)屬性值,用來當(dāng)做equalTo的參數(shù)弥锄,表示某個(gè)控件的寬度屬性
* 如果添加了下面的宏丧靡,mas\_width也可以寫成width
define MAS_SHORTHAND
* mas\_height、mas\_centerX以此類推
* 可有可無的用法
* 以下方法都僅僅是為了提高可讀性籽暇,可有可無
-(MASConstraint *)with {
return self;
}
- (MASConstraint *)and {
return self;
}
* 約束的動(dòng)畫
* 先改變約束對象的值:
self.redViewW.constant = 50;
* 然后刷新整個(gè)視圖
[UIView animateWithDuration:2.0 animations:^{
// 強(qiáng)制刷新
[self.view layoutIfNeeded];
}];
* UILabel實(shí)現(xiàn)包裹內(nèi)容
* 設(shè)置寬度約束<= 固定值
* 設(shè)置位置約束
* 不需要設(shè)置高度約束
* 萬能公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value
#UIScrollView
![Snip20170126_76.png](http://upload-images.jianshu.io/upload_images/1609505-474e79dff8a45bc8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170126_78.png](http://upload-images.jianshu.io/upload_images/1609505-b07066abe4a08973.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170126_79.png](http://upload-images.jianshu.io/upload_images/1609505-2b3d68a17bc5b949.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![Snip20170127_81.png](http://upload-images.jianshu.io/upload_images/1609505-4d3f78969d36162e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#控制器view的延遲加載
- 控制器的view是延遲加載的:用到時(shí)再加載
- 可以用isViewLoaded方法判斷一個(gè)UIViewController的view是否已經(jīng)被加載
- 控制器的view加載完畢就會(huì)調(diào)用viewDidLoad方法
#總結(jié)
* 先搭建界面温治,然后向服務(wù)器發(fā)送請求,獲取網(wǎng)絡(luò)數(shù)據(jù)戒悠,解析網(wǎng)絡(luò)數(shù)據(jù)(xml/json),將其分別轉(zhuǎn)換成模型數(shù)據(jù)熬荆,以數(shù)組方式存儲(chǔ),最后遍歷顯示到相應(yīng)控件上去绸狐。
* 重復(fù)代碼需要抽方法
* 可以考慮將經(jīng)常變的數(shù)據(jù)放在文件中進(jìn)行存儲(chǔ)卤恳,程序啟動(dòng)后從文件中讀取最新的數(shù)據(jù)。如果要變動(dòng)數(shù)據(jù)六孵,直接修改數(shù)據(jù)文件即可纬黎,不用修改代碼