一 、使用git管理工程
1、可以使用OSChina遠程管理工程(免費) 2、可以使用GitHub網站進行遠程管理(付費) 注冊--登錄--創建資源庫
二、通過coco管理我們的第三方框架
1、通過命令加載到我們的工程統計的文件夾 2.命令行pod init 創建pod file 文件 3、命令行pod search +第三方框架的名字 ,進行搜索 4、搜索到第三方框架,把最新的版本復制到我們的podfile文檔 5、選擇我們鍵盤上的Q退出 6、命令行安裝我們的第三方框架pod install
三、在本地checkout
1、使用Xcode進行checkout,把資源加載到本地 2、用xocde創建工程,把工程放方到和git同級的文件,讓git管理工程 3、創建完工程,commit--push到我們的OSChana遠程服務管理器
四、開始我們的環境配置
1、打開生成的新生成的工程對應的工程 2、配置我們的環境 3、工程的唯一標示,(一般的時候都是我們的公司名稱網址的反寫,例如com.520it.www.+我們工程的名字) 4、工程的版本,如果是新開發的工程,一般是1.0,如果是迭代開發,每次發布的版本必須比我們的上一次發布的版本要高 5、配置我們工程的文件的前綴(在右邊--例如LYH) 6、配置我們是配手機的版本,一般最多比我們最新版本低三級 7、配置我們手機的橫豎屏 8、配置我們啟動App的status bar style 9、配置我們App的圖標AppIcon 10、配置我們啟動App的Launch image Source 選擇BrandAssets 11、選擇我們是否選擇加載Storyboard
五、正式開始我們的工程--控制器的選擇(以百思不得姐為例)
1、首先顯示我們的窗口 2、選擇tabBarController為我們的根控制器 3、選擇navegationController為我們根控制器的第一個根控制器 4、選擇tableViewController為我們的nav的根控制器
六、工程的部署
1、劃分工程的結構
2、刪除工程的文件智能在Xcode中刪除
3.git不會把空文件夾上傳到遠方的服務器
4、封裝:可以做到自己的事情自己做
5、tabBarController切換原理:點擊tabBar上的按鈕,就會把子控制器的View添加到tabBarController,把之前的View移除掉
6、在自定義的tabBarController中搭建我們的主流框架
7、添加對應的控制器到對應的位置
8、添加完畢子控制器
9.tabBar按鈕出現的問題解決
(1)、按鈕選中的時候,圖片被渲染
原因:蘋果默認設置渲染顏色,為藍色
解決:1.直接修改圖片 :設定我們的圖片為original2.通過代碼 創建分類設定圖片不被渲染
(2)、按鈕被選中的時候,文字被渲染,設置字體大小
原因:蘋果默認設置渲染顏色,為藍色
解決:文字在tabBar按鈕上,文字的屬性有tabBarItem決定,(建議在tabBarController中進行統一設置 1、通過在方法l-(void)load中進行設置文字屬性,此方法在程序啟動的時候加載 2、在+ (void)initialize 中進行設置,此方法在類第一次使用或者子類第一次使用的時候加載)
(3)、中間發布按鈕顯示不出來
10、關于獲取所有的控件的方法說明appearence
1.appearance是什么?UIAppearance協議里面一個方法
2.任何對象都可以使用appearance?不能,只有遵守了UIAppearance協議,才能使用UIAppearance,所有的控件都可以使用appearance
3.任何屬性都可以通過appearance去設置嗎?不是任何屬性都可以通過appearance設置
4.哪些屬性可以通過appearance去設置,只有有UI_APPEARANCE_SELECTOR宏屬性才可以通過appearance去設置
5.如果一個屬性通過appearance去設置,必須要保證在顯示之前去設置
//獲取所有UITabBarItem外觀
UITabBarItem*item = [UITabBarItemappearance];
//文字顏色為黑色
//字典描述文字信息
NSMutableDictionary*attr = [NSMutableDictionarydictionary];
attr[NSForegroundColorAttributeName] = [UIColorblackColor];
//設置選中狀態下文字顏色
[itemsetTitleTextAttributes:attrforState:UIControlStateSelected];
11、關于文字渲染的問題
設置文字不要渲染
//技巧:以后不要給我記方法,忘記,直接跳入頭文件去查找
//通過富文本屬性去設置文字顏色,字體,陰影,下劃線,圖文混排等等
// tabBarItem:模型通過富文本屬性設置字符串
// tabBarItem不是按鈕,只是按鈕對應模型
12、設置文字的大小
設置tabBar上文字的大小只有設置文字在正常狀態下的文字大小,在選中狀態下無法設置文字的大小
NSMutableDictionary*attr = [NSMutableDictionarydictionary];
attr[NSForegroundColorAttributeName] = [UIColorblackColor];
//設置選中狀態下文字顏色
[itemsetTitleTextAttributes:attrforState:UIControlStateSelected];
//設置正常狀態下文字字體
NSMutableDictionary*attrNor = [NSMutableDictionarydictionary];
attrNor[NSFontAttributeName] = [UIFontsystemFontOfSize:13];
[itemsetTitleTextAttributes:attrNorforState:UIControlStateNormal];
13、關于中間圖片不顯示問題
主要原因是中間按鈕被渲染
14、關于中間圖片位置錯亂問題
重新把一個按鈕添加到tabBar上,建議在Viewdidload中加載,設置懶加載
15、關于導航條按鈕點擊范圍較大問題
默認一個按鈕,超出按鈕點擊范圍,將無法點擊,如果能夠點擊影響用戶體驗
為什么把一個按鈕包裝成UIBarButtonItem就會出現點擊范圍較大
解決:不能把一個按鈕包裝成UIBarButtonItem;
創建分類,提供接口,把我們需要的Item作為方法返回
+ (instancetype)itemWithImage:(UIImage*)image highImage:(UIImage*)highImage target:(id)target action:(SEL)action
{
UIButton*btn = [UIButtonbuttonWithType:UIButtonTypeCustom];
[btnsetImage:imageforState:UIControlStateNormal];
[btnsetImage:highImageforState:UIControlStateHighlighted];
[btnsizeToFit];
[btnaddTarget:targetaction:actionforControlEvents:UIControlEventTouchUpInside];
UIView*containerView = [[UIViewalloc]initWithFrame:btn.bounds];
[containerViewaddSubview:btn];
return[[UIBarButtonItemalloc]initWithCustomView:containerView];
}
16、關于導航條上中間文字的屬性設置
顯示哪個子控制器,對應的子控制器就可以設置對應的文字標題屬性,文字屬性是有navgetionbar決定的。
17、關于導航條處理細節
要想設置全局的導航條主標題文字設置:
建議在主流框架的navgetion獲取當前類的全局導航條,設置導航條的字體為想要設定的字號。
eg://設置導航條標題字體=>導航條
NSMutableDictionary*attr = [NSMutableDictionarydictionary];
attr[NSFontAttributeName] = [UIFontboldSystemFontOfSize:22];
//獲取全局導航條外觀
//??? [UINavigationBar appearance];
// iOS7,發短信功能,聯系人黑屏=>使用appearance,去設置導航條背景圖片
//獲取哪個類下的導航條,管理自己下導航條
UINavigationBar*bar = [UINavigationBarappearanceWhenContainedIn:self,nil];
[barsetTitleTextAttributes:attr];
18、關于返回按鈕的設置;
- (void)pushViewController:(UIViewController*)viewController animated:(BOOL)animated,關于push的調用是每次push的時候,都會調用,把push的控制器壓入棧頂控制器中,
設置除根控制器的每次push的控制器左邊按鈕為想要的返回按鈕的樣式;(注意:??每次設置左邊的按鈕的時候必須在跳轉之前設置);
eg:- (void)pushViewController:(UIViewController*)viewController animated:(BOOL)animated
{
//設置棧頂控制器
//設置返回按鈕
UIButton*backButton = [UIButtonbuttonWithType:UIButtonTypeCustom];
[backButtonsetTitle:@"返回"forState:UIControlStateNormal];
[backButtonsetTitleColor:[UIColorblackColor]forState:UIControlStateNormal];
[backButtonsetTitleColor:[UIColorredColor]forState:UIControlStateHighlighted];
[backButtonsetImage:[UIImageimageNamed:@"navigationButtonReturn"]forState:UIControlStateNormal];
[backButtonsetImage:[UIImageimageNamed:@"navigationButtonReturnClick"]forState:UIControlStateHighlighted];
[backButtonsizeToFit];
//設置內容內邊距,修改按鈕位置
backButton.contentEdgeInsets=UIEdgeInsetsMake(0, -30,0,0);
[backButtonaddTarget:selfaction:@selector(back)forControlEvents:UIControlEventTouchUpInside];
UIView*containView = [[UIViewalloc]initWithFrame:backButton.bounds];
[containViewaddSubview:backButton];
UIBarButtonItem*item = [[UIBarButtonItemalloc]initWithCustomView:containView];
viewController.navigationItem.leftBarButtonItem= item;
//真正在執行跳轉
[superpushViewController:viewControlleranimated:animated];
}
19 關于滑動返回的設置
??導航控制器跟我們設置了push之后自動返回功能,這個功能是ios7開始的,如果我們自己設置了導航條左側返回按鈕,覆蓋了系統的返回按鈕,那么左側邊緣的滑動返回功能就會失效,這個時候我們需要通過代碼來實現左側滑動返回功能
蘋果設置左側返回失效,可能系統內部對手勢功能做了一些設置
這個時候我們需要看蘋果做了哪些事情,我們把蘋果做的事情取消就可以了,
- (void)viewDidLoad {
[superviewDidLoad];
//清空滑動返回手勢代理,恢復滑動返回功能
self.interactivePopGestureRecognizer.delegate=self;
//假死狀態:界面死,程序還在跑
//原因:在根控制器下,滑動返回
//解決:控制滑動手勢什么時候有效,什么時候失效
//干掉手勢,沒有滑動返回功能,
//手勢失效,通過代理
//??? self.interactivePopGestureRecognizer.delegate = self;
}
#pragma mark -UIGestureRecognizerDelegate
//是否觸發手勢
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch
{
//在根控制器下失效,在非根控制器有效
returnself.childViewControllers.count>1;
}
通過查找我們知道蘋果內部把手勢的代理手勢用戶交互為NO(是否觸發手勢),所以只要我們重新設置代理,然后把用戶交互觸發手勢設置在非根控制器為YES就可以了
20、關于設置全屏的左滑功能
這個時候我們需要先禁用系統自帶的左側邊緣滑動,然后重新進行設置代理,調用系統的手勢方法,然后設置手勢滑動在非根控制器下為YES;
21、設置程序啟動的時候AD廣告界面
設置廣告界面為在程序啟動完畢的時候為我們的根控制器,(其中還必須能夠顯示啟動圖片)
通過XIB來創建我們的廣告界面,其中廣告圖片來自網絡,所以我們不能加載本地圖片,要加載網絡圖片這個時候我們就用到了占位思想,這里就是設置占位圖片。
22、設置我們的啟動圖片的屏幕適配問題
- (void)setupLanuchImage
{
//不同屏幕尺寸使用不同圖片
//屏幕適配
//判斷屏幕尺寸
// iPhone6P:736 iPhone6:667 iPhone5:568 iPhone4:480
UIImage*image =nil;
if(iPhone6P) {// iPhone6P
image = [UIImageimageNamed:@"LaunchImage-800-Portrait-736h@3x"];
}elseif(iPhone6) {
image = [UIImageimageNamed:@"LaunchImage-800-667h"];
}elseif(iPhone5) {
image = [UIImageimageNamed:@"LaunchImage-568h"];
}elseif(iPhone4) {
image = [UIImageimageNamed:@"LaunchImage"];
}
_lanuchImageView.image= image;
}
23加載網絡圖片這個時候我們需要加載第三方框架
第三方框架的管理,使用cocoapods,使用它的好處是可以自動加載我們需要的第三方框架的依賴,不需要我們手動再去加載,因為我們在開發的時候并且會自動更新我們的第三方框架。
24、通過第三方框架加載AFN加載數據
1)創建我們的會話管理者,讓會話管理者發送請求
2)如果遇到請求失敗,看返回給我們請求失敗的原因,
eg:content-type;
25、廣告的跳轉
給廣告的imageView設置一個點按手勢(??imageView默認時不能與用戶交互的,必須讓圖片的能夠與用戶交互,設置enabled = YES);
26、廣告的時間設定
通過實踐定時器,設置廣告的時長,通過static設定只給變化的時間參數分配一次空間,
//添加倒計時功能
_timer= [NSTimerscheduledTimerWithTimeInterval:1target:selfselector:@selector(timeChange)userInfo:nilrepeats:YES];
}
- (void)timeChange
{
staticinti =3;
i--;
if(i == -1) {
//計時結束
[selfjump:nil];
}
//設置按鈕標題
NSString*title = [NSStringstringWithFormat:@"跳過(%d)",i];
[_jumpButtonsetTitle:titleforState:UIControlStateNormal];
}
27 、 標簽界面的設定
創建標簽控制器
28、自定義cell
建議通過XIB+代碼的形式創建自定義cell,給cell上的空間設置數據
29、加載數據
通過查詢數據的接口文檔查詢要加載的數據,發送網絡請求
30、訂閱數字的修改
通過NSString設定想要加載的數據
31、頭像圓角的設置
兩種方式:
(1)、通過layer的剪切
(2)、通過圖像的上下文剪切
if(image ==nil)return;
// 1.開啟圖形上下文
// opaque:不透明度YES:黑色NO:透明
// scale:比例因子(像素與點比例) 0:自動識別當前比例因子
UIGraphicsBeginImageContextWithOptions(image.size,NO,0);
// 2.描述裁剪區域
UIBezierPath*clipPath = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0, image.size.width, image.size.height)];
// 3.設置裁剪區域
[clipPathaddClip];
// 4.畫圖
[imagedrawAtPoint:CGPointZero];
// 5.從上下文取出圖片
image =UIGraphicsGetImageFromCurrentImageContext();
// 6.關閉上下文
UIGraphicsEndImageContext();
// 7.一定要給控件重新賦值
_iconView.image= image;
32、tableView的分割線為樣式
(1)、自定義分割線
通過去處系統的分割線,加上自己制定一的分割線
(2)設置系統屬性,讓分割線占據全屏
//版本適配iOS7
iOS多了一個屬性separatorInset
self.tableView.separatorInset=UIEdgeInsetsZero;
版本IOS8
多了一個約束邊緣屬性
layerMargins
if(version >=8.0) {//判斷當前版本
cell.layoutMargins=UIEdgeInsetsZero;
}
******想要重新設定cell的尺寸,那么cell又一個setframe
可以在這里面設定cell的尺寸
- (void)setFrame:(CGRect)frame
{
//??? frame.origin.y += 1;
//??? frame.origin.x += 10;
frame.size.height-=1;
//??? frame.size.width -= 20;
//真正去設置frame
[supersetFrame:frame];
}
33、指示器效果
主要要與用戶加載網絡數據的時候提醒用戶的功能,還必須了解,view消失的時候需要做的事情,
34、關于文字換行
35、當一個界面比較復雜時,把界面分成幾個模塊,還有我們要考慮使用封裝的思想,便于應對界面的變化
36、文本框的占位顏色
這個屬性屬于視圖,所以可以通過tintcolor來設置
eg:self.tintColor= [UIColorwhiteColor];
37、關于文本框的占位文字顏色
因為文本框沒有給我們提供文本框的占位文字顏色設置,所以我們
只能設置占位文字的屬性來設置占位文字的顏色,
eg://初始化文本框占位文字顏色
NSMutableDictionary*attr = [NSMutableDictionarydictionary];
attr[NSForegroundColorAttributeName] = [UIColorlightGrayColor];
NSAttributedString*attrStr = [[NSAttributedStringalloc]initWithString:self.placeholderattributes:attr];
self.attributedPlaceholder= attrStr;
38、快捷設置文本框占位文字顏色
可以通過設置分類來給占位文字增加顏色屬性
@proprety UIColor * placeholder;
-(void)setPlaceholder:(UIColor *)color {
NSMutableDictionary*attr = [NSMutableDictionarydictionary];
attr[NSForegroundColorAttributeName] = placeholderColor;
NSAttributedString*attrStr = [[NSAttributedStringalloc]initWithString:self.placeholderattributes:attr];
self.attributedPlaceholder= attrStr;
}
39、考慮占位文字是什么空間,可能是UILable,所以如果能拿到UILable
我們只要設置UILalbe的就可以設置占位文字的顏色textColor
如果類沒有給我們提供空間,我們可以通過斷點和小面包查看是什么空間,然后通過KVC
取出空間,給空間設置屬性,
//猜測占位文字是UILabel =>驗證占位文字是UILabel(通過小面包查看當前界面是哪個類) =>設置占位文字顏色=>拿到這個占位文字label做事情=>蘋果木有提供這樣屬性給我拿這個控件=>思考:有些屬性可能存在,但是是私有沒有暴露給我們=>查看下這個類私有屬性名(1.runtime 2.斷點) => KVC
//直接獲取控件去設置
UILabel*placeholderLabel = [selfvalueForKey:@"placeholderLabel"];
placeholderLabel.textColor= placeholderColor;
40、怎樣設置讓空間的設置屬性沒有先后順序
OC的機制是懶加載,用到的時候在加載,所以要想設置沒有先后順序可以判斷空間
有沒有占位文字,如果沒有。我們在設置字符長度為空
// OC是懶加載,用到的時候才會去加載
//直接獲取控件去設置
//注意點:判斷字符串有沒有內容根據長度判斷
if(self.placeholder.length==0) {
self.placeholder=@" ";
}
//獲取控件
UILabel*placeholderLabel = [selfvalueForKey:@"placeholderLabel"];
//設置顏色
placeholderLabel.textColor= placeholderColor;
41、對于固定不變的頁面我們一般可以通過storyboard來創建
42、設置我的界面的collectionView的分割線
我們可以通過設置間隙來設置collectionView的分割線
43、為了方便我們看代碼,我們一般都會通過抽取,來是代碼跟一目了然
之前我們一直都是通過把自己的功能放倒自己的功能模塊,現在我們可以通過
UICollectionView*collectionView = ({
collectionView = [[UICollectionViewalloc]initWithFrame:CGRectMake(0,0,0,300)collectionViewLayout:layout];
collectionView.backgroundColor= [UIColorclearColor];
//設置數據源.展示cell
collectionView.dataSource=self;
//注冊cell
[collectionViewregisterNib:[UINibnibWithNibName:@"XMGSquareCell"bundle:nil]forCellWithReuseIdentifier:ID];
collectionView;
});
44、關于網絡數據的加載和模型轉換
獲取網絡數據-查看接口文檔--創建會話管理者--設置請求參數--發送請求--接受數據--先寫入plist文件,設置模型參數,字典數組轉模型,傳遞數據,設置到對應的cell上。
45、關于collection的行高
求出collection的實際行高,計算出footerView的實際行高我們在重新把值賦值給footerView。
46、關于collectionView空格子的處理
格子的多少有模型決定所以我們要修補空格子,就必須修改模型
47、點擊cell進入網頁
展示網頁:
1.UIWebView好處:在當前app打開網頁,弊端:沒有功能,自己去實現,(進度條)
2.Safari:好處:默認有很多好用功能(進度條,地址欄,前進,后退,刷新)弊端:必須要跳出當前app
3.在當前app展示網頁,而且想要有safari功能,自定義UIWebView
4.SFSafariViewController:Safari iOS9展示網頁,當前app展示網頁,有safari所有功能
ios8 有一個Webkit顯示網頁;
通過KVO監聽來改變,網頁的進退;
48、清楚內存的設置
通過獲取出的尺寸和位置來達到計算內存的大小和位置
49、獲取文件夾的尺寸
1、獲取NSFileManager對象
2、獲取文件夾里面的所有文件
3、遍歷文件夾的所有文件
4、拼接文件全路徑
5、attributesItemAtPath:指定一個文件全路徑
6、獲取文件尺寸,疊加起來
//獲取文件夾尺寸
- (NSInteger)getSizeOfDirectoryPath:(NSString*)directoryPath
{
// 1.獲取NSFileManager對象
NSFileManager*mgr = [NSFileManagerdefaultManager];
// 2.獲取文件夾里面所有文件
// subpathsAtPath:獲取文件夾里面所有子路徑,包含多級.
NSArray*subpaths = [mgrsubpathsAtPath:directoryPath];
NSIntegertotalSize =0;
// 3.遍歷文件夾里所有文件
for(NSString*fileNameinsubpaths) {
// 4.拼接文件全路徑
NSString*filePath = [directoryPathstringByAppendingPathComponent:fileName];
//判斷下是否是隱藏文件或者是文件夾
if([fileNamehasPrefix:@"."])continue;//隱藏文件
//判斷下是否是文件夾
BOOLisDirectory;
[mgrfileExistsAtPath:filePathisDirectory:&isDirectory];
if(isDirectory)continue;//文件夾
// 5.獲取文件屬性
NSDictionary*attr = [mgrattributesOfItemAtPath:filePatherror:nil];
// 6.疊加文件尺寸
totalSize += [attrfileSize];
}
returntotalSize;
}
50、在cell上顯示數據
拼接字符和數據就可以
51、清楚緩存
思路:1、點擊cell的時候刪除全路徑下所有文件
2、創建路徑下文件夾‘
3、修改數據為0
4、刷新列表。
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
//清除緩存
// 1.刪除文件夾
[[NSFileManagerdefaultManager]removeItemAtPath:XMGCachePatherror:nil];
// 2.創建文件夾
[[NSFileManagerdefaultManager]createDirectoryAtPath:XMGCachePathwithIntermediateDirectories:YESattributes:nilerror:nil];
//刷新表格
_totalSize=0;
[self.tableViewreloadData];
//??? [[SDImageCache sharedImageCache] clearDisk];
}
52、封裝業務類
封裝的要求
1、業務類頂部,寫清楚這個類是干什么的
2、每個方法都必須有文檔主食,外界調用的時候有提示
3、每個功能,一定要嚴謹判斷。
eg:我們的文件緩存處理
/**
*功能:處理文件夾
*/
@interfaceXMGFileManager :NSObject
/**
*指定一個文件夾路徑,獲取這個文件夾尺寸
*
*? @param directoryPath文件夾全路徑
*
*? @return文件夾尺寸
*/
+ (NSInteger)getSizeOfDirectoryPath:(NSString*)directoryPath;
/**
*刪除文件
*
*? @param filePath刪除文件全路徑
*/
+ (void)deleteOfFilePath:(NSString*)filePath;
53、關于處理緩存的時候App卡頓的現象解決
因為所有文件的拼接和查詢文件都是在主線程中執行,所以會造成主線程的卡頓,所以我們要把耗時的操作都放在,
之線程中操作,所以這個時候我們可以痛喲Block傳遞參數,把操作放在子線程中,就不會造成主線程卡頓
dispatch_async(dispatch_get_global_queue(0,0), ^{
// 2.獲取文件夾里面所有文件
// subpathsAtPath:獲取文件夾里面所有子路徑,包含多級.
NSArray*subpaths = [mgrsubpathsAtPath:directoryPath];
NSIntegertotalSize =0;
// 3.遍歷文件夾里所有文件
for(NSString*fileNameinsubpaths) {
// 4.拼接文件全路徑
NSString*filePath = [directoryPathstringByAppendingPathComponent:fileName];
//判斷下是否是隱藏文件或者是文件夾
if([fileNamehasPrefix:@"."])continue;//隱藏文件
//判斷下是否是文件夾
BOOLisDirectory;
[mgrfileExistsAtPath:filePathisDirectory:&isDirectory];
if(isDirectory)continue;//文件夾
// 5.獲取文件屬性
NSDictionary*attr = [mgrattributesOfItemAtPath:filePatherror:nil];
// 6.疊加文件尺寸
totalSize += [attrfileSize];
}
dispatch_sync(dispatch_get_main_queue(), ^{
/**
*一定要記得回到主線程
*/
if(completion) {
completion(totalSize);
}
});
});
54、精華界面的搭建
關于精華界面的搭建,如果我們使用UIScrollerView就會造成離屏渲染,渲染也會創建很多對象,比較消耗內存
所以我們可以使用,UICollectionView來代替UIScrollerView,collectionView幫我們
實現了離屏渲染的問題。因為cell的重用機制
那么如何處理數據的錯亂呢,我們可以在馬上要顯示的Cell上一處之前的view,再把我們喲啊吸顯示的view添加到我們的cell上
55、如何顯示topView頂部條的標題
我們可以仿照tabBar的設計。來設置頂部條,因為每個控制器都有,一個titel屬性,所以,我們可以把控制器的title屬性賦值,然后創建頂部條的標題時,把控制器的條內容賦值給Btn
56、監聽頂部按鈕的點擊
但點擊按鈕的時候讓對應的按鈕處于選中狀態(重要的三部曲)
57、監聽滾動完成然tableView處于對應的狀態
1、點擊按鈕的時候把要顯示的view添加到cell上
2、滾動cell的時候讓按鈕 滾動到對應的位置
58、添加按鈕底部條的下劃線
可以在添加按鈕的時候,把底部條,默認放在第一個按鈕的下邊,但點擊
按鈕的時候把底部條改變X的的位置,處于對應按鈕的下邊,當滾動cell的時候讓其處于對應的按鈕下邊
59、對于一個App里面我們可以重復利用的界面,可以進行封裝,方便我們重復利用
封裝的要求是:把不改變的進行封裝,改變的另外寫一個類。
60、對于不等高的cell的搭建
對于比較復雜的cell我們需要靜心模塊封裝,防止以后對要變動的改變
eg:我們的精華cell可以分為,頂部View,中間View,熱評的View,底部View
61、頂部View的搭建
頂部View建議通過XIB+代碼的方式進行搭建,
62、請求數據
通過AFN第三方框架我們進行請求數據,
查看接口文檔-查看請求參數-發送請求-進行文檔解析 -數據轉模型
63、解析數據的過程
先要查看數據結構--看是否需要序列化--不需要序列化截取我們需要的shuju
--字典轉模型--刷新列表
64、分析控件的frame
想要計算空間的frame,必須在我們請求數據成功之后進行frame計算
??:盡量不要在heightforRow計算我們的行高,因為調用過于頻繁,會造成界面卡頓
計算cell的高度,可以通過獲取字體的字號和文字的寬度進行計算
65、MVVM框架
VM :視圖模型 ?專門處理界面的業務邏輯,(計算空間的位置,點擊事件)
思路:進行數據轉模型完之后,這個時候我們需要計算出空間的行高,如果在控制器中計算顯得控制器代碼過于臃腫,這個時候我們可以使用MVVM框架來對控制器進行減負處理,把控制器管理
控件的frame和點擊等事件靜心VM處理。
VM的處理,就是把數據模型傳遞給視圖模型,視圖模型把計算好的frame儲存到視圖模型,然后給視圖傳遞視圖模型,展示數據。
66、搭建中間圖片的View
中間圖片的View搭建,其實和頂部視圖搭建方法相似,參考頂部view的搭建過程
67、關于中間圖片frame高度的計算
首先判斷是不是文本cell,如果不是,就計算cell的frame
關于frameH的計算,讓圖片的高度和寬度進行等比列計算,
68、關于cell的循環利用
當是文本的時候我們需要隱藏cell的中間view,不是文本的時候讓hidden的屬性為NO
69、對于大圖的處理
我們可以設置當圖片尺寸大于屏幕的高度的高度的時候設置圖片的高度,這個時候還需要設置圖片的壓縮性,
70、關于大圖的處理
對于大圖不能占據屏幕寬度,我們可是使用繪制圖片獲得一張新圖,來重新布置圖片
71、加載圖片的進度處理
我們一般使用第三方框架來處理,對于精華加載圖片的樣式可以使用DALabeledCircularProgressView來調用其中的方法來實現,加載圖片的進度
72、加載音頻
加載音頻的過程和之前加載圖片的過程基本相似
創建音頻的View--通過XIB進行設計音頻的圖形設計--查看接口文檔定義屬性
--傳遞視圖模型--設置圖形的frame,給音頻View傳遞數據,連線設置數據
73、搭建視頻View
和加載音頻過程類似:
創建視頻的View--通過XIB進行設計視頻的圖形設計--查看接口文檔定義屬性
--傳遞視圖模型--設置圖形的frame,給視頻View傳遞數據,連線設置數據
74、搭建最熱評論
過程和加載視頻過程類似
創建最熱評論的View--通過XIB進行設計最熱評論的圖形設計--查看接口文檔定義屬性
--傳遞視圖模型--設置圖形的frame,給最熱評論View傳遞數據,連線設置數據
??加載最熱評論的數據屬性:
其中涉及到加載過程屬性嵌套的問題,這個時候我們需要對數據進行分析,MJE不會幫我們轉換NSArray的屬性,這個時候我們需要告訴它,我們要加載的數組屬性是哪個類或者再次使用MJ轉換模型
- (void)setTop_cmt:(NSArray*)top_cmt
{
_top_cmt= top_cmt;
if(top_cmt.count) {
NSDictionary*commentDict = top_cmt.firstObject;
_hotCommentItem= [XMGCommentItemmj_objectWithKeyValues:commentDict];
}
}
/*****************************************/
//告訴MJ,數組中字典轉換成哪個模型
+ (NSDictionary*)mj_objectClassInArray
{
return@{@"top_cmt":@"XMGCommentItem"};
}
//在賦值之前,MJ就已經把這個數組中字典轉換好模型,把模型包裝到數組,傳遞給你
- (void)setTop_cmt:(NSArray*)top_cmt
{
_top_cmt= top_cmt;
if(top_cmt.count) {
_hotCommentItem= top_cmt.firstObject;
}
}
??:如果模型中有模型會自動幫我們轉換為模型
如果模型中有數組,就不會幫我們轉換為模型
//如果模型中有模型,會自動幫你轉換好
//如果模型中有數組,數組中是字典,就不會把數組中字典轉換成模型
@interfaceXMGCommentItem :NSObject
@property(nonatomic,strong)NSString*content;
@property(nonatomic,strong)NSString*voicetime;
@property(nonatomic,strong)NSString*voiceuri;
@property(nonatomic,strong)XMGUserItem*user;
75、底部工具條的搭建
創建底部工具條的View--通過XIB進行設計底部工具條的圖形設計--查看接口文檔定義屬性
--傳遞視圖模型--設置圖形的frame,給底部工具條View傳遞數據,連線設置數據
??:底部接受的數據進行處理。
if(count >10000.0) {
CGFloatvalue = count /10000.0;
title = [NSStringstringWithFormat:@"%.1f萬",value];
title = [titlestringByReplacingOccurrencesOfString:@".0"withString:@""];
}elseif(count >0){
title = [NSStringstringWithFormat:@"%ld",count];
}
[buttonsetTitle:titleforState:UIControlStateNormal];
76、關于cell外觀的設計
主要是cell的方法set frame的應用。
77、cell頂部點擊更多的處理。
主要是當點擊更多數據的傳遞,(代理,block,通知的應用)
//通知:讓兩個沒有關系對象,產生聯系,用于多級傳遞
//代理:1.逆傳2.封裝自己控件
// block:1.用于參數2.逆傳(替換代理)
2)想要拿到控制器做事情,就想到根控制器
// Modal =>只要有控制器
//以后想要快速獲取控制器,就拿窗口的根控制器
[[UIApplicationsharedApplication].keyWindow.rootViewControllerpresentViewController:alertVcanimated:YEScompletion:nil];
78、關于時間的處理
NSDateFormatter時間格式的處理
關于NSCalendar日期元素的獲取
//?利用NSCalendar處理日期
NSCalendar*calendar?=?[NSCalendarcurrentCalendar];
NSIntegermonth?=?[calendar?component:NSCalendarUnitMonthfromDate:date];
NSIntegerhour?=?[calendar?component:NSCalendarUnitHourfromDate:date];
NSIntegerminute?=?[calendar?component:NSCalendarUnitMinutefromDate:date];
獲取時間的間隔:
//?獲得createdAtDate和nowDate的時間間隔(間隔多少秒)
//? ? NSTimeInterval?interval?=?[nowDate?timeIntervalSinceDate:createdAtDate];
NSTimeIntervalinterval?=?[createdAtDate?timeIntervalSinceNow];
//?獲得日期之間的間隔
NSCalendarUnitunit?=NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
NSDateComponents*cmps?=?[calendar?components:unit?fromDate:createdAtDate?toDate:otherDate?options:0];
NSLog(@"%@",?cmps);
增加的日期分類
- (NSDateComponents*)deltaWithNow
{
//獲取當前時間
NSDate*currentDate = [NSDatedate];
//獲取日歷
NSCalendar*calendar = [NSCalendarcurrentCalendar];
//獲取兩個日期差值
return[calendarcomponents:NSCalendarUnitHour|NSCalendarUnitMinutefromDate:selftoDate:currentDateoptions:NSCalendarWrapComponents];
}
- (BOOL)isThisYear
{
//獲取當前時間
NSDate*currentDate = [NSDatedate];
//獲取當前時間年份日期組件對象
NSCalendar*calendar = [NSCalendarcurrentCalendar];
//指定一個日期,就返回這個日期的日期組件
//獲取當前時間日期組件
NSDateComponents*curCmp = [calendarcomponents:NSCalendarUnitYearfromDate:currentDate];
//獲取發布時間日期組件
NSDateComponents*postCmp = [calendarcomponents:NSCalendarUnitYearfromDate:self];
//判斷下年份是否與當前時間相等
returncurCmp.year== postCmp.year;
}
- (BOOL)isToday
{
//獲取當前日歷類
NSCalendar*curCalendar =[NSCalendarcurrentCalendar];
return[curCalendarisDateInToday:self];
}
- (BOOL)isYesterday
{
//獲取當前日歷類
NSCalendar*curCalendar =[NSCalendarcurrentCalendar];
return[curCalendarisDateInYesterday:self];
}
79、大圖的展示
創建控制器展示想要展示的圖片
80、關于圖片的縮放
因為scrollerView自帶縮放功能,所以只要我們實現代理方法,實現代理方法
告訴系統我們要讓那個控件具有縮放功能,
然后設置視圖的縮放比列即可,
81、如何向系統相冊保存一張圖片
首先獲取要保存的圖片,然后實現系統寫入照片的方法,
UIImageWriteToSavedPhotosAlbum(_imageView.image,self,@selector(image:didFinishSavingWithError:contextInfo:),nil);
必須調用系統指定的方法,然后用指示器告訴用戶保存成功和失敗
- (void)image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
{
if(error) {
//保存失敗
[SVProgressHUDshowErrorWithStatus:@"保存失敗"];
}else{
//保存成功
[SVProgressHUDshowSuccessWithStatus:@"保存成功"];
}
}
82、如何把下載好的相冊保存到自己的相冊中
蘋果保存圖片到自己的相冊中有自己的邏輯,先把相冊保存到系統中,然后再把相冊從系統中,拷貝一份到自己的
相冊中
photos框架:專門處理相冊
如何學習新的框架:1、學習這個框架中常用的類,怎么知道框架中哪些類常用,
(百度/蘋果的官方文檔)
photos常用的類:PHPhotosLibrary:相簿(所有相冊的集合)
PHAsset:圖片(資源文件)
PHAssetCollection :相冊
PHAssetCreatRequest:創建,修改,刪除圖片
PHAssetCollectionResquest:創建,修改刪除相冊
photos框架使用的規則: ? 要操縱相冊或者相片,必須發送請求
如何了結一個類怎么使用:
1、跳轉頭文件,查看怎么使用
2、按住option,查看PHPhotosLibrary
業務邏輯:
在相薄中進行
1、創建自己的相冊(相冊請求類創建相冊)
2、創建圖片請求
3、添加圖片到相冊
4、用戶授權
83、怎樣解決,每次添加圖片都會重新創建一個新的相冊
通過獲取系統相冊,然后遍歷系統所有相冊,看是否有相冊和要創建的相冊同名
有就返回,沒有救不返回,
然后判斷系統是否有相冊,有相冊就創建圖片請求
沒有救創建相冊
84、相冊的封裝
85、添加上拉刷新,
其實就是添加tableView的底部footerView
86、上拉刷新邏輯
什么時候進行上拉刷新數據
上拉控件,完全顯示的時候,才會加載數據
當用戶拖動的時候,判斷上拉什么時候現實完畢刷新數據
怎樣知道是刷新的新數據,必須記錄上一頁最大的maxTime
記錄下來
87、關于下拉懸浮的處理
就是在下拉停止拖動的時候設置下拉偏移量。