最近呢專案任務不是很緊張,打算呢寫一下東西來充實一下自己,所以打算找一些APP來仿寫它們的介面,或者根據它們的產品自己來寫一些自己想實現的介面,為了能更好的學習與進步,希望有心看到這篇文章的讀者,如果有更好的思路或實現方法的能提出來,這樣大家可以一同進步與提高,架構呢主要還是MVC
,後期會慢慢的像MVVM + RAC
來遷移。
這次模仿的是百度傳課主要有以下打算
1.實現一個首頁
2.寫一個語音識別的介面,基於訊飛(http://www.xfyun.cn/?ch=bdtg)
3.根據時間來寫一個詳情介面
這篇文章實現的首頁如下
首先拿到一個UI介面呢我們不應該悶頭去寫他,我們首先得看它包含幾個部分,怎麼實現比較容易,多用模型的思想,降低程式碼的耦合,讓程式碼的可擴充套件性提高,在寫的過程中注意程式碼的質量,能一句解決的程式碼絕不寫兩句程式碼,對自己嚴格要求的過程中自己會慢慢提高。
拿到這個介面看到有三種形式的內容,頭部一個輪播圖,中間一個滾動圖,下部一個很普通的cell
我首先想到了兩種思路:
- 思路一
將上面的兩種形式當成tableView的header來實現,本文就是如此實現 - 思路二
將上面兩種形式直接當做tableView的cell,給tableView的資料來源中新增模型,在其代理方法中實現取資料的時候判斷是哪一種模型顯示那種cell。
以上兩種思路都能實現,個人感覺實現複雜度相當,可擴擴充套件性好,如果有更好實現思路的夥伴可以提出您寶貴的意見。
實現過程如下
1.看到輪播圖,很高興,因為上一篇文章中我已經封裝過一個輪播圖,直接拿過來用即可。
2.下面滾動更簡單,可以用ScrollView上新增ImageView或者直接使用collectionView
3.非常常見的cell,利用xib來做,傳模型,重寫setter
方法。
分清楚以上步驟以後接下來我們該實現了,我們需要一個網路下載工具類,基於AFNetworking
,為了更顯符合實際專案,我們稍微封裝一下,基於block回傳,當然大型的專案為了耦合性低也可以使用代理的方法
1 2 3 4 5 6 7 8 9 10 11 12 |
#import #import @interface HTTPToolRequest : NSObject + (void)GETURLString:(NSString *)urlString parameters:(NSDictionary *)paramaters progressBlock:(void(^)(NSProgress * downloadProgress))downloadProgressBlock sucessBlock:(void(^)(id responseObject))sucessBlock failureBlock:(void(^)(NSString *error))failureBlock; + (void)GETURLString:(NSString *)urlString parameters:(NSDictionary *)paramaters sucessBlock:(void(^)(id responseObject))sucessBlock failureBlock:(void(^)(NSString *error))failureBlock; @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#import "HTTPToolRequest.h" #define TIMEOUTInterval 10 @implementation HTTPToolRequest + (AFHTTPSessionManager *)generalManager { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer.timeoutInterval = TIMEOUTInterval; //header設定 //通用設定 根據具體介面的要求,MD5加密什麼的 /** [manager.requestSerializer setValue:@"" forHTTPHeaderField:@""]; */ /** 設定接收資料的型別*/ manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain",@"text/html",@"application/json", nil]; return manager; } + (void)GETURLString:(NSString *)urlString parameters:(NSDictionary *)paramaters progressBlock:(void(^)(NSProgress * downloadProgress))downloadProgressBlock sucessBlock:(void(^)(id responseObject))sucessBlock failureBlock:(void(^)(NSString *error))failureBlock { AFHTTPSessionManager *manager = [self generalManager]; [manager GET:urlString parameters:paramaters progress:^(NSProgress * _Nonnull downloadProgress){ downloadProgressBlock(downloadProgress); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { sucessBlock(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSString *errorStr = [error.userInfo objectForKey:@"NSLocalizedDescription"]; failureBlock(errorStr); }]; } + (void)GETURLString:(NSString *)urlString parameters:(NSDictionary *)paramaters sucessBlock:(void(^)(id responseObject))sucessBlock failureBlock:(void(^)(NSString *error))failureBlock { AFHTTPSessionManager *manager = [self generalManager]; [manager GET:urlString parameters:paramaters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { sucessBlock(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSString *errorStr = [error.userInfo objectForKey:@"NSLocalizedDescription"]; failureBlock(errorStr); }]; } @end |
下面我們該到主頁實現tableView了,建立都採用懶載入形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
//輪播圖資料來源 - (NSMutableArray *)recommendArray { if (!_recommendArray){ _recommendArray = [NSMutableArray array]; } return _recommendArray; } //普通cell的資料來源 - (NSMutableArray *)focusArray { if (!_focusArray){ _focusArray = [NSMutableArray array]; } return _focusArray; } //滾動資料來源 - (NSMutableArray *)AlbumArray { if (!_AlbumArray) { _AlbumArray = [NSMutableArray array]; } return _AlbumArray; } - (UITableView *)mainTableView { if (!_mainTableView) { _mainTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, SCREENWIDTH, SCREENHEIGHT - 49 - 64) style:UITableViewStylePlain]; _mainTableView.rowHeight = 80; _mainTableView.delegate = self; _mainTableView.dataSource = self; _mainTableView.tableHeaderView = self.bgView; } return _mainTableView; } //頭部的背景view - (UIView *)bgView { if (!_bgView) { _bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, 200 + 90)]; [_bgView addSubview:self.loopView]; } return _bgView; } //輪播view - (scrollLoopView *)loopView { if (!_loopView) { _loopView = [[scrollLoopView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, 200)]; _loopView.delegate = self; } return _loopView; } |
在viewDidLoad實現網路資料來源的下載,切記由於下載是耗時操作,需在下載完後賦值給資料來源重新整理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.automaticallyAdjustsScrollViewInsets = NO; [self.view addSubview:self.mainTableView]; __weak typeof(self) weakself = self; [HTTPToolRequest GETURLString:@"http://pop.client.chuanke.com/?mod=recommend&act=mobile&client=2&limit=20" parameters:nil sucessBlock:^(id responseObject) { for (NSInteger i = 0; i |
針對以上說一個小技巧,我們在建立模型的時候,常常要寫一大堆噁心的@property(nonatomic, copy) NSString *name;
垃圾程式碼,遇到這個就噁心的想吐,我就想能不能自動給我生成了,你還別說網上github上就有這種軟體,有興趣的可以去搜一下,但是作為一個程式設計師不能老想著用別人的東西,所以我就給NSObject
新增一個分類,當傳入一個字典會自動生成列印處理,接下來需要做的就是command + c
然後command + v
到自己的模型中,然後採用了李明傑大神的MJExtension.h
這個框架給模型資料資料賦值的方式(也就是執行時的方式),或者大家也可以通過KVC
來賦值,都可以,下面提供生成屬性程式碼的分類
1 2 3 4 5 6 7 8 9 10 11 12 |
#import @interface NSObject (propertyCode) /** * 自動生成屬性申明Code * * @param dict 傳入的字典 */ + (void)propertyCodeWithDictionary:(NSDictionary *)dict; @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#import "NSObject+propertyCode.h" @implementation NSObject (propertyCode) // 自動生成屬性宣告的程式碼 + (void)propertyCodeWithDictionary:(NSDictionary *)dict { NSMutableString *strM = [NSMutableString string]; [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { NSString *str; NSLog(@"%@",[obj class]); if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")] || [obj isKindOfClass:NSClassFromString(@"NSTaggedPointerString")] || [obj isKindOfClass:NSClassFromString(@"__NSCFConstantString")]) { str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSString *%@;",key]; } if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]) { str = [NSString stringWithFormat:@"@property (nonatomic, assign) int %@;",key]; } if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]) { str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSArray *%@;",key]; } if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]) { str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSDictionary *%@;",key]; } if ([obj isKindOfClass:NSClassFromString(@"__NSCFBoolean")]) { str = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",key]; } [strM appendFormat:@"\n%@\n",str]; }]; NSLog(@"%@",strM); } |
接下來是資料來源代理相關方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#pragma mark - UITableViewDataSource,UITableViewDelegate - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.recommendArray.count ; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { HomeTableViewCell *cell = [HomeTableViewCell getTableView:tableView]; cell.courseList = [self.recommendArray objectAtIndex:indexPath.row]; return cell; } - (void)tapView:(UITapGestureRecognizer *)tap { NSLog(@"點選了第%zd",tap.view.tag); } //滾動圖的實現,為了方便起見利用ScrollView實現,首推UICollectionView - (void)setupAlubm { UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 200, SCREENWIDTH, 90)]; scroll.contentSize = CGSizeMake([self.AlbumArray count] *(SCREENWIDTH - 10*2 - 10)/2 , 0); for (NSInteger i = 0; i |
以上呢實現這個主要的介面,歡迎有好的意見的夥伴提出寶貴的意見,如果有不明白或者不理解的地方大家可以留言,下一篇主要分享訊飛語音識別的實現。
本文會傳一個簡易的gitHub的連結,供有興趣的好學者參考,歡迎土豪打賞,你的一丁丁打賞是我不斷寫下去的動力!!!
https://github.com/markdashi/baiduCourse
最後嚴重宣告一點,文章所提供的介面是根據code4app
相關專案中的獲得,只供學習使用,請勿濫用或者破壞使用,否則相關責任由相關責任人來承擔!