iOS-Contacts( TableView)

  • [ ] 準備階段:數據層model
    ?

請求數據-ContactsService

?

  • 寫一個mock網絡請求獲取JSON數據的方法:

?

+ (void)getContactsCompleteBlock:(void (^)(ContactsListEntity *contactsListEntity, NSError *error))completeBlock;
?

提示:此方法不需要傳入參數
?

  • 方法的實現:使用<ServiceProvider/ServiceProvider> 中network的方法:
    ?
-(NSURLSessionDataTask *)requestAPI:(NSString *)apiName nameSpace:(NSString *)nameSpace parameters:(NSDictionary *)parameters options:(SPNetworkOptions)options complete:(void (^)(NSURLResponse *, SPNetworkResponseObject *, NSError *))complete {
    return [self fetchMockByAPIName:apiName parameters:parameters complete:complete];
}

提示:這里請求的API即為請求的JSON文件的前綴:@"getContactList"
?

  • complete block的實現:
    獲得的返回的responseObject的entity,并用它初始化contactsListEntity
    ?
ContactsListEntity *contactsListEntity = [[ContactsListEntity alloc] initWithDictionary:responseObject.entity];

?
沒有出錯的情況下,即error為nil,completeBlock返回contactsListEntity完成回調。
?
?

解析數據

?

1、JSON數據

在工程中對應的mock文件夾中創建getContactList-alimockapi.json文件

  • 設計JSON格式
  1. 一層:array contactList
  2. 二層:contactList中元素為一個個cell的信息(dictionary)
    這里包含信息是,key:contactName、contactId、contactAdd、contactNumber
    提示:value都是string類型的。
    ?

2、ContactsListEntity

  • property:
    ?
@property (nonatomic, strong) NSArray *contacts;
?
  • method:重寫AliEntity中的映射方法,這里面解析方法都已經寫好,可以理解為這里是調用一個接口,只需要告訴它名稱的對應關系即可。
    ?
 +(NSDictionary *)arrayItemMap;
?
 +(NSDictionary *)propertyMap;
  1. propertyItemMap 自定義映射關系。這里把JSON中的某數據結構(例如這里是數組:contactList)賦值給ContactsListEntity中名為contacts的成員變量。
return @{@"contactList" : @"contacts"};
  1. arrayItemMap 定義數組中的item都應該是什么類型。這里是指JSON中對應的數組contactList應該由ContactsInfoEntity組成。
    ?
    ?

3、ContactsInfoEntity

  • property:
    ?
@property (nonatomic, copy) NSString *contactName;
@property (nonatomic, copy) NSString *contactId;
@property (nonatomic, copy) NSString *contactNumber;
@property (nonatomic, copy) NSString *contactAddress;

?

  • method:重寫Entity中的映射方法。道理同listEntity。
    提示:此Entity中的屬性名如果與JSON中相同,則可以省去映射步驟。若不同,則需要單獨處理。
    ?
 + (NSDictionary *)propertyMap {
    return @{@"contactAdd" : @"contactAddress"};
}

?
?
?
?
?
?

  • [ ] 準備階段:視圖層view
    ?

數據綁定-ContactsTableViewCell

?
1、自動調用UITableViewCell初始化方法:
?

 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier NS_AVAILABLE_IOS(3_0) NS_DESIGNATED_INITIALIZER;

2、cell初始化函數commonInit:
初始化子view,并將其添加到父視圖
?

     _checkContainerView = [UIView new];
    [self.contentView addSubview:_checkContainerView];

?
3、設計布局,使用Masonry 添加約束
?
使用mas_maekConstraints設置約束條件:mas_equalTo
示例:
?

[textView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(StyleSpacing2);
        make.top.mas_equalTo(StyleSpacing4);
        make.bottom.mas_equalTo(StyleSpacing4);
        make.right.mas_equalTo(StyleSpacing2);
    }];

注意添加約束要在addSubview之后。
?
?
4、public method:實現數據綁定
?

 - (void)configWithContactsInfoEntity:(ContactsInfoEntity *)entity;
?

將ContactsInfoEntity中屬性值賦值給cell中的lable.text
示例:
?

self.contactName.text = entity.contactName;

提示:cell這里容易出錯,詳見Contacts報錯總結。
?
?
?
?

  • [ ] 開始“動工”:控制層controller

控制層-ContactsViewController

?

viewController生命周期:

?

viewDidLoad:

  • 初始化tableView
    ?
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
  • 設置tableView的其他屬性(背景顏色、分割樣式等等)
  • 給tableView綁定delegate、datasource
    ?
self.tableView.delegate = self;
    self.tableView.dataSource = self;
  • 將tableView添加到父視圖
    ?
[self.view addSubview:self.tableView];

?

  • 調用加載數據方法reloadData
    ?
    ?

viewDidAppear:

?

 - (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}

?
其他生命周期過程省略。
?
?

加載數據-reloadData

?
這個方法是用來加載數據的,數據就是從mock網絡請求獲取而來的,既然如此,那么之前精心準備的ContactsService就華麗登場啦:
?

[ContactsService getContactsCompleteBlock:^(ContactsListEntity *contactsListEntity, NSError *error) {
        if (!error) {
            
            NSLog(@"contacts : %@", contactsListEntity);
            self.contactsListEntity = contactsListEntity;
            [self.tableView reloadData];
            
        } else {
            
            NSLog(@"error : %@", error.localizedDescription);
            
        }
    }];

?
請求數據成功之后,在無錯誤的情況下completeBlock執行:把成功返回的contactsListEntity傳給本地的contactsListEntity。
?
?

TableView Delegate&Datasource

  • delegate:
    ?
 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

?
因為暫無特殊要求,這里高度直接設置為了固定值。
?
?

  • datasource:
    1、列表行數
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
?

?
列表行數返回的是加載數據成功后的contactListEntity中數組contacts的元素數。
?

return self.contactsListEntity.contacts.count;
}

?
2、cell
?

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

?
此時,就要用到之前準備的ASCContactsTableViewCell啦。
先實例化一個它的對象cell:

 ContactsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContactsTableViewCell" forIndexPath:indexPath];

?
然后用加載數據成功后的contactListEntity中數組contacts的某個元素內容去構造這個cell,調用ASCContactsTableViewCell類的方法:

[cell configWithContactsInfoEntity:self.contactsListEntity.contacts[indexPath.row]];

?
最后返回這個cell,工程主體就大功告成啦!
?
?
?
?

  • [ ] 用起來~

功能入口-AliMyAlibaba

修改view

在頁面內添加一個新的headerButton,與原有的三個button:“Favorite Companies、Favorite Products、Browsing History” 并列放置。


DingTalk20170719140008.png
DingTalk20170719140008.png

?
?
?

添加響應事件

為新設置的按鈕添加響應方法actContacts
?

 - (void)actContacts {//跳轉聯系人頁面
    [UT ctrlClicked:@"MyContacts" page:self args:nil];
    [AccountHelper executeUserRequiredAction:^{
        ContactsViewController *cc= [[ContactsViewController alloc] initWithNibName:nil bundle:nil];
        [self.navigationController pushViewController:cc animated:YES];
    }];
}

這里就實例化了ContactsViewController類的對象,并通過push的方法顯示出來。那么這個功能的入口就寫好了,可以用起來啦~


DingTalk20170719145934.png
DingTalk20170719145934.png

?
加個聯系人頭像美化一下:
?


DingTalk20170719201748.png
DingTalk20170719201748.png

?
再添加一個下拉翻頁功能,好啦~任務完成了~
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容