標籤:
因為是自訂的組件所以storyboard我們就用不了啦,所有的代碼都必須手寫,這樣才能保證組件使用的靈活性和減少各個組件之間的耦合性,更利於團隊之間的合作。在封裝組件時要預留好外界可能使用到的介面,和返回該返回的資料。
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
//把使用過的圖片存入sqlite
NSData *imageData = UIImagePNGRepresentation(image);
[copy_self.imageMode save:imageData ImageText:imageText];
@property (nonatomic,readwrite) CLLocationCoordinate2D coordinate;
CocoaPods應該是iOS最常用最有名的類庫管理工具了,可以用來方便的統一管理這些第三方庫。
安裝CocoaPods需要Ruby環境
Mac OS本身內建Ruby,但還是更新一下保險,
APP目錄: AppDelegate :這個目錄下放的是AppDelegate.h(.m)檔案,是整個應用的入口檔案,所以單獨拿出來。
Macro:這個目錄下放了整個應用會用到的宏定義,
Macro
|- AppMacro.h: 放app相關的宏定義
|- NotificationMacro.h:放的是通知相關的宏定義
|- VendorMacro.h:放一些第三方常量
|- UtilsMacro.h:放的是一些方便使用的宏定義
Vendors:這個目錄放第三方的類庫/SDK
Resources:這個目錄下放的是app會用到的一些資源,主要是圖片
KVO是實現Cocoa Bindings的基礎,它提供了一種方法,當某個屬性改變時,相應的objects會被通知到 這是怎麼實現的呢?其實這都是通過Objective-C強大的運行時(runtime)實現的
運行時(runtime):
- (void)parseObject:(id)object {
for (id data in object) {
if ([[data type] isEqualToString:@"String"]) {
[self parseString:[data value]];
} else if ([[data type] isEqualToString:@"Number"]) {
[self parseNumber:[data value]];
} else if ([[data type] isEqualToString:@"Array"]) {
[self parseArray:[data value]];
}
}
}
- (void)parseObjectDynamic:(id)object {
for (id data in object) {
[self performSelector:NSSelectorFromString([NSString stringWithFormat:@"parse%@:", [data type]]) withObject:[data value]];
}
}
- (void)parseString:(NSString *)aString {}
- (void)parseNumber:(NSString *)aNumber {}
- (void)parseArray:(NSString *)aArray {}
方法由兩個部分組成。Selector相當於一個方法的id;IMP是方法的實現。這樣分開的一個便利之處是selector和IMP之間的對應關係可以被改變。比如一個 IMP 可以有多個 selectors 指向它。 IMP 是一個指向方法實現的指標
能讓我們使用block作為 IMP,下面這個程式碼片段展示了如何使用block來添加新的方法。
IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
NSLog(@"Hello %@", string);
});
class_addMethod([MYclass class], @selector(sayHello:), myIMP, "[email protected]:@");
Core Graphics是一組用來繪製2D圖形的API
Core Animation包含於QuartzCore.framwork中,是一組自由度更大的圖形繪製和動畫API,
Core Image是一組用於映像、視頻處理的API,如添加濾鏡之類的。
iOS中,所有的UIView都內建了一個CALayer(可以通過UIView.layer訪問),UIView的渲染和動畫最終也是通過layer來實現的。從這個意義上說,UIView就是簡單的一層殼,把圖形繪製需要的資訊傳遞給layer。當然UIView還有一個重要的功能就是處理事件,如點擊按鈕,滑動等等。
所以一般的動畫view animation都可以應付。
重點就是模組化編程 多用組合,少用繼承;模組化編程好處:只要介面是對的,且功能也正常,每個模組只要完成自己的功能就行了,出了問題,也只需要調整某一個模組,而不用擔心會引發其他模組功能的異常。
模組之間是互盲的,A模組不需要知道B模組的存在,更不能依賴B模組,這樣才能解耦(話雖如此,實際上經常會自然不自然地與某個模組發生耦合)。模組只需要提供介面供母體使用就行了。當然在特定事件發生時,還需要通知母體,這就需要用到delegate。
使用繼承會使架構變得複雜,為了保證每個類都只有自己需要的方法,需要很小心地定義public / protected / private方法,尤其是對父類地改動更需小心,這種架構很難應對多變的環境。
使用組合可以讓每一個模組專註於自己地功能,按需使用,模組的調整隻要不影響介面,愛怎麼折騰就怎麼折騰,提升了自由度。
不過組合也是有副作用的,尤其是涉及到子模組,比如上面的BallComponent,需要重新定義一遍介面,而繼承的話就沒有這個問題。有一些公用的屬性和方法也可以通過繼承來實現,比如所有的Component都繼承自BaseComponent。
所以盡量多用組合,少用繼承。
為了隱藏我們使用的控制項和控制項回調的方法,我們在ViewController.m中用延展來對我們的控制項和方法進行聲明。
//把ImageView添加到view的最底層
[self.view insertSubview:self.backView atIndex:0];
//音/視頻播放器時間的變化(定時器執行的方法)
-(void) time
{
//擷取音訊總時間
NSTimeInterval totalTimer = self.player.duration;
//擷取音訊目前時間
NSTimeInterval currentTime = self.player.currentTime;
//根據時間比設定進度條的進度
self.progress.progress = (currentTime/totalTimer);
//把秒轉換成分鐘
int currentM = currentTime/60;
currentTime = (int)currentTime`;
int totalM = totalTimer/60;
totalTimer = (int)totalTimer`;
//把時間顯示在lable上
NSString *timeString = [NSString stringWithFormat:@".0f:.0f|.0f:.0f",currentM, currentTime, totalM,totalTimer];
self.label.text = timeString;
}
下面是iOS提供的一些管理子視圖的方法,常用方法如下:
(1) initWithFrame : 通過frame初始化視圖,參數為CGRectMake(x, y, width, height);
(2) insertSubView: atIndex: 往指定層上插入視圖,哪個View調用該方法,index就是相對於誰。
(3) insertSubView: aboveSubView: 在某個視圖上插入子視圖。
(4) insertSubView: belowSubView: 在某個子視圖的後面添加一個新的視圖
(5) bringSubViewToFront: 把子視圖放到最前
(6) sendSubViewToBack: 把子視圖放到最後
(7) exchangeSubviewAtIndex: withSubviewAtIndex: 交換兩個視圖的前後順序
(8) removeFromSuperview: 從父視圖中移除view
(9) -(void) addSubview: (UIView *) view 添加一個視圖
視圖的層次用index來區分,這個值從0開始以步長1依次增加,index為0的時候代表視圖層次的最底層,
擷取Storyboard建立的ViewController:
//擷取storyboard: 通過bundle根據storyboard的名字來擷取我們的storyboard,
UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
//由storyboard根據myView的storyBoardID來擷取我們要切換的視圖
UIViewController *myView = [story instantiateViewControllerWithIdentifier:@"myView"];
//由navigationController推向我們要推向的view
[self.navigationController pushViewController:myView animated:YES];
在一個NavigationController中只有一個NavigationBar, 而在一個NavigationController下的各個ViewController都有屬於自己的NavigationBarItem.
//往右側添加一個按鈕
11 self.navigationItem.rightBarButtonItem = item1;
12
13 //往右側添加兩個按鈕
14 self.navigationItem.rightBarButtonItems = @[item1, item2];
CoreData的配置和使用步驟還是挺複雜的 所以盡量少用;
如何記錄使用者的登陸狀態呢?就用NSUserDefault. NSUserDefault設定完值以後要進行同步 NSUserDefault是蘋果提供給我們用來儲存使用者的登陸資訊的一個類,當然是持久化的了
//擷取UserDefaults單例
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//移除UserDefaults中儲存的使用者資訊
[userDefaults removeObjectForKey:@"name"];
[userDefaults removeObjectForKey:@"password"];
[userDefaults synchronize];
知識點5