//
// AppDelegate.h
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (retain, nonatomic) UIWindow *window;

@end


//
// AppDelegate.m
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import "AppDelegate.h"

import "RootViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    RootViewController *rootVC = [[RootViewController alloc]init];
    UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:rootVC];
    self.window.rootViewController = navi;
    [rootVC release];
    [navi release];
    [_window release];

    return YES;
    }

  • (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }
  • (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
  • (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }
  • (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }
  • (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

@end



//
// RootViewController.h
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end


//
// RootViewController.m
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import "RootViewController.h"

import "MyTableViewCell.h"

import "NSString+Characters.h"

@interface RootViewController ()<UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, retain) UITableView *tablrView;
@property (nonatomic, retain) NSMutableArray *dataArr;

//
@property (nonatomic, retain) NSMutableDictionary *contactDic;// 联系人字典
@property (nonatomic, retain) NSArray *keyArr;// 分区名数组 可变不可变都可以
@end

@implementation RootViewController

  • (void)dealloc
    {

    [_tablrView release];
    [_dataArr release];
    [super dealloc];

    }

  • (void)viewDidLoad {

    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    
    // tableView
    // 通过属性创建对象时 一定要用self.xx = (setter方法, 防止提前被释放)
    self.tablrView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    self.tablrView.delegate = self;
    self.tablrView.dataSource = self;
    [self.view addSubview:self.tablrView];
    // 平衡alloc的引用计数时 一定要用[_xx release];
    [_tablrView release];
    
    // 数据处理
    [self dataHandler];

    }

/// 数据处理

  • (void)dataHandler
    {
    // 获取plist
    NSString *path = [[NSBundle mainBundle]pathForResource:@"ContactList" ofType:@"plist"];
    NSArray *arr = [NSArray arrayWithContentsOfFile:path];
    // self.dataArr = [arr mutableCopy];
    // 数组-> 字典+数组
    self.contactDic = [NSMutableDictionary dictionary];
    // 遍历 数据源
    for (NSDictionary *dic in arr) {

    // 首字母
    NSString *capLetter = [dic[@"name"]firstCharacterOfName];
    // 获取对应数组
    NSMutableArray *tempArr = _contactDic[capLetter];
    if (tempArr) {
        // 如果存在
        [tempArr addObject:dic];
    }   else{
        // 不存在 创建后添加
        tempArr = [NSMutableArray array];
        [tempArr addObject:dic];
        [_contactDic setObject:tempArr forKey:capLetter];
    }

    }
    // 保存所有的key (排序后)
    self.keyArr = [_contactDic.allKeys sortedArrayUsingSelector:@selector(compare:)];

    }

pragma mark - tableView的协议方法

  • (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
    // 分组数
    return _contactDic.count;
    }
  • (NSString )tableView:(UITableView )tableView titleForHeaderInSection:(NSInteger)section
    {
    // 分区头
    return _keyArr[section];
    }
  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {

warning 使用数组赋值cell时 如果number设置为固定值 一般回崩溃 数组越界

// 分区中行数
NSString *key = _keyArr[section];
NSArray *arr = _contactDic[key];

return arr.count;

}

  • (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (!cell) {

    cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"] autorelease];
    

    }
    // 赋值
    // NSDictionary *dic = _dataArr[indexPath.row];

// cell.textLabel.text = dic[@"name"];
// cell.detailTextLabel.text = dic[@"phone"];

// 联系人信息获取
NSString *key = _keyArr[indexPath.section];
NSArray *arr = _contactDic[key];
NSDictionary *dic = arr[indexPath.row];

// 自定义cell赋值

warning 如果cell上内容 出现重叠 1.使用属性赋值时 误使用系统属性 2.控件属性的frame设置发生遮盖

cell.nameLabel.text = dic[@"name"];
cell.phoneLabel.text = dic[@"phone"];
cell.hobbyLabel.text = dic[@"hobby"];
return cell;

}

  • (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath
    {
    return 200;
    }
  • (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

/*

pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.

    }

*/

@end



//
// MyTableViewCell.h
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import <UIKit/UIKit.h>

@interface MyTableViewCell : UITableViewCell
@property (nonatomic, retain) UILabel *nameLabel;
@property (nonatomic, retain) UILabel *phoneLabel;
@property (nonatomic, retain) UILabel *hobbyLabel;
@end


//
// MyTableViewCell.m
// UI11_UITablView综合练习
//
// Created by YIem on 15/12/21.
// Copyright © 2015年 www.yiem.net YIem博客. All rights reserved.
//

import "MyTableViewCell.h"

@implementation MyTableViewCell

pragma mark - dealloc

  • (void)dealloc
    {

    [_nameLabel release];
    [_phoneLabel release];
    [_hobbyLabel release];
    [super dealloc];

    }

pragma mark - 初始化方法

  • (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (style) {

    // 初始化自定义cell上的控件
    // name
    self.nameLabel = [[UILabel alloc] init];
    _nameLabel.backgroundColor = [UIColor orangeColor];
    [self.contentView addSubview:_nameLabel];
    [_nameLabel release];
    // phone
    self.phoneLabel = [[UILabel alloc]init];
    _phoneLabel.backgroundColor = [UIColor redColor];
    [self.contentView addSubview:_phoneLabel];
    [_phoneLabel release];
    // hobby
    self.hobbyLabel = [[UILabel alloc]init];
    _hobbyLabel.backgroundColor = [UIColor grayColor];
    [self.contentView addSubview:_hobbyLabel];
    [_hobbyLabel release];

    }
    return self;
    }

  • (void)layoutSubviews
    {
    [super layoutSubviews];
    _nameLabel.frame = CGRectMake(20, 20, self.contentView.bounds.size.width - 40, 40);
    CGRect f = _nameLabel.frame;
    f.origin.y += 60;
    _phoneLabel.frame = f;
    f.origin.y += 60;
    _hobbyLabel.frame = f;
    }
  • (void)awakeFromNib {

    // Initialization code

    }

  • (void)setSelected:(BOOL)selected animated:(BOOL)animated {

    [super setSelected:selected animated:animated];
    
    // Configure the view for the selected state

    }

@end