UITableView综合 ??????????????????
通讯录实战
Controller
HomeTableViewController.m
#import "HomeTableViewController.h" #import "DetailViewController.h" #import "AddViewController.h" #import "DataHandle.h" #import "Person.h" @interface HomeTableViewController () { DataHandle *datahandle; } @end @implementation HomeTableViewController - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"通 讯 录"; self.navigationItem.rightBarButtonItem = self.editButtonItem; self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemAdd) target:self action:@selector(add)] autorelease]; self.tableView.rowHeight = 110; self.tableView.tableFooterView = [[UIView new] autorelease]; datahandle = [DataHandle defaultDataHandle]; } - (void)add { // AddViewController *addVC = [[AddViewController alloc] init]; // [self.navigationController pushViewController:addVC animated:YES]; // [addVC release]; UINavigationController管理的视图控制器, 都是具有明显层级关系的, 页面的切换使用push和pop 当页面之间没有明显的层级关系, 页面跳转使用模态形式做切换 模态切换的步骤 1.创建下一个页面 AddViewController *addVC = [[AddViewController alloc] init]; 模态切换的两个视图是没有层级关系的, 并且后一个视图不会继承前一个视图的导航栏, 后一个视图的导航栏需要自己来加 UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:addVC]; 修改动画效果 navigation.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 2.从当前页面, 模态切换到下一个页面 [self presentViewController:navigation animated:YES completion:^{ NSLog(@"已经切换"); }]; 3.释放 [addVC release]; [navigation release]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return datahandle.titleArray.count; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return datahandle.titleArray[section]; } - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return datahandle.titleArray; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { /* //获取分区标题 NSString *key = datahandle.titleArray[section]; //通过标题, 获取对应value(存放联系人数组) NSMutableArray *array = datahandle.personDic[key]; */ //返回 return [[datahandle.personDic valueForKey:datahandle.titleArray[section]] count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier ]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifier]; } 数组某个person对象 Person *person = [datahandle.personDic valueForKey:datahandle.titleArray[indexPath.section]][indexPath.row]; 在cell上显示 cell.textLabel.text = person.name; cell.detailTextLabel.text = person.phone; cell.imageView.image = person.image; NSLog(@"%@", datahandle.titleArray); return cell; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { //删除数据 BOOL result = [datahandle deletePersonWithIndexPath:indexPath]; if (result) { //创建分区位置 NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:indexPath.section]; //删除分区 [tableView deleteSections:indexSet withRowAnimation:(UITableViewRowAnimationFade)]; } else { //删除cell [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationFade)]; } } } - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { [datahandle movePersonAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; 当时视图将要出现的时候, 刷新数据 [self.tableView reloadData]; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 往单例内存数据 // DataHandle *dataHandle = [DataHandle defaultDataHandle]; // dataHandle.name = [NSString stringWithFormat:@"%ld分区%ld行", indexPath.section, indexPath.row]; // DetailViewController *detailVC = [[DetailViewController alloc] init]; datahandle.person = datahandle.personDic[datahandle.titleArray[indexPath.section]][indexPath.row]; [self.navigationController pushViewController:detailVC animated:YES]; } - (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { 判断是否同一个区 if (sourceIndexPath.section != proposedDestinationIndexPath.section) { return sourceIndexPath; } else { return proposedDestinationIndexPath; } } @end
DetailViewController.m
#import "DetailViewController.h"
#import "DataHandle.h"
#import "Person.h"
@interface DetailViewController ()
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:0.986 green:1.000 blue:0.569 alpha:1.000];
从单例中取数据
// DataHandle *dataHandle = [DataHandle defaultDataHandle];
// self.navigationItem.title = dataHandle.name;
DataHandle *handle = [DataHandle defaultDataHandle];
self.navigationItem.title = handle.person.name;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.jpg"]];
imageView.frame = CGRectMake(20, 100, 113, 160);
imageView.userInteractionEnabled = YES;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image =handle.person.image;
[self.view addSubview:imageView];
[imageView release];
NSArray *array = @[handle.person.name, handle.person.gender, handle.person.age, handle.person.phone];
for (NSInteger i = 0; i < 4; i++) {
UILabel *label = [[UILabel alloc] init];
label.text = array[i];
label.tag = 101 + i;
label.backgroundColor = [UIColor whiteColor];
[self.view addSubview:label];
[label release];
}
UILabel *nameLabel = (UILabel *)[self.view viewWithTag:101];
nameLabel.frame = CGRectMake(143, 100, 375 - 163, 40);
UILabel *genderLabel = (UILabel *)[self.view viewWithTag:102];
genderLabel.frame = CGRectMake(143, 160, (375 - 173) / 2, 40);
UILabel *ageLabel = (UILabel *)[self.view viewWithTag:103];
ageLabel.frame = CGRectMake( CGRectGetMaxX(genderLabel.frame) + 10, 160, (375 - 173) / 2 , 40);
UILabel *phoneLabel = (UILabel *)[self.view viewWithTag:104];
phoneLabel.frame = CGRectMake(143, 220, 375 - 163, 40);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
AddViewController.m
#import "AddViewController.h"
#import "Person.h"
#import "DataHandle.h"
#import "HomeTableViewController.h"
@interface AddViewController ()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@property (nonatomic, retain) UIImageView *imageView;
@property (nonatomic, retain) UITextField *nameTextField, *genderTextField, *ageTextField, *phoneTextField;
@end
@implementation AddViewController
- (void)dealloc {
[_imageView release];
[_nameTextField release];
[_genderTextField release];
[_ageTextField release];
[_phoneTextField release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:0.805 green:1.000 blue:0.934 alpha:1.000];
self.navigationItem.title = @"添加联系人";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemCancel) target:self action:@selector(cancel)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemSave) target:self action:@selector(save)];
// self.imageView = [UIImage imageNamed:@"1.jpg"];
// UIImageView *image = [[UIImageView alloc] initWithImage:_imageView];
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.jpg"]];
self.imageView.frame = CGRectMake(20, 100, 113, 160);
self.imageView.userInteractionEnabled = YES;
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
[self.view addSubview:self.imageView];
[self.imageView release];
NSArray *array = @[@"姓名", @"性别", @"年龄", @"电话号码"];
for (NSInteger i = 0; i < 4; i++) {
UITextField *textField = [[UITextField alloc] init];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.placeholder = array[i];
textField.clearsOnInsertion = YES;
textField.tag = 101 + i;
[self.view addSubview:textField];
[textField release];
}
self.nameTextField = (UITextField *)[self.view viewWithTag:101];
self.nameTextField.frame = CGRectMake(143, 100, 375 - 163, 40);
self.genderTextField = (UITextField *)[self.view viewWithTag:102];
self.genderTextField.frame = CGRectMake(143, 160, (375 - 173) / 2, 40);
self.ageTextField = (UITextField *)[self.view viewWithTag:103];
self.ageTextField.frame = CGRectMake( CGRectGetMaxX(self.genderTextField.frame) + 10, 160, (375 - 173) / 2 , 40);
self.phoneTextField = (UITextField *)[self.view viewWithTag:104];
self.phoneTextField.frame = CGRectMake(143, 220, 375 - 163, 40);
//创建手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[self.imageView addGestureRecognizer:tap];
[tap release];
}
- (void)save {
if (self.nameTextField.text.length == 0 || self.phoneTextField.text.length == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"姓名或电话不能为空" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alertView show];
[alertView release];
return;
}
创建一个person对象
Person *person = [[Person alloc] init];
person.name = self.nameTextField.text;
person.gender = self.genderTextField.text;
person.age = self.ageTextField.text;
person.phone = self.phoneTextField.text;
person.image = self.imageView.image;
把person对象存入单例
DataHandle *dataHandle = [DataHandle defaultDataHandle];
[dataHandle addPerson:person];
[person release];
返回
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)tap {
调用系统相册
UIImagePickerController, 系统相册, 继承于UINavigationController
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
[self presentViewController:picker animated:YES completion:^{
NSLog(@"系统相册");
}];
}
- (void)cancel {
模态返回
[self dismissViewControllerAnimated:YES completion:^{
NSLog(@"已经返回");
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIImagePickerControllerDelegate
//已经完成图片选择
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
self.imageView.image = image;
[picker dismissViewControllerAnimated:YES completion:nil];
}
Model
Person.h
#import <Foundation/Foundation.h>
只有导入UIKit的框架, 才能使用UI开头的类
#import <UIKit/UIKit.h>
@interface Person : NSObject
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) NSString *name, *gender, *age, *phone;
@end
Person.m
#import "Person.h"
@implementation Person
- (void)dealloc {
[_image release];
[_name release];
[_gender release];
[_age release];
[_phone release];
[super dealloc];
}
- (NSString *)description
{
return [NSString stringWithFormat:@"name: %@ gender: %@ age: %@ phone: %@", _name, _gender, _age, _phone];
}
@end
DataHandle.h
#import <Foundation/Foundation.h>
单例模式, 保证一个类生成的对象只有一个
注意
1.通过单例模式封装的类, 创建对象必须使用defaultDataHandle方法
2.单例模式创建的对象, 不用释放, 当程序结束时会自动释放
3.单例模式创建的对象, 不能存过大的数据
@class Person;
@interface DataHandle : NSObject
//@property (nonatomic, retain) NSString *name;
当项目中很多页面都会使用到某个数据时(比如通讯录中各个页面都会使用联系人信息), 一般都会把这个数据存放到单例中
@property (nonatomic, retain) NSMutableDictionary *personDic;
@property (nonatomic, retain) NSMutableArray *titleArray;
@property (nonatomic, retain) Person *person;
创建单例的方法
1.类方法
2.返回值类型: 当前类
3.方法名: main/default/shared + 类名
+ (DataHandle *)defaultDataHandle;
添加联系人
- (void)addPerson:(Person *)person;
删除联系人
- (BOOL)deletePersonWithIndexPath:(NSIndexPath *)indexpath;
移动联系人
- (void)movePersonAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
@end
Person.m
#import "DataHandle.h"
#import "Person.h"
@implementation DataHandle
- (void)dealloc {
// [_name release];
[_personDic release];
[_titleArray release];
[super dealloc];
}
+ (DataHandle *)defaultDataHandle {
static DataHandle *datahandle = nil;
if (datahandle == nil) {
datahandle = [[DataHandle alloc] init];
数组和字典必须初始化, 开辟内存空间后, 才能使用
加号方法, self相当于类DataHandle
调用setter方法, 应该使用对象
datahandle.personDic = [NSMutableDictionary dictionaryWithCapacity:0];
datahandle.titleArray = [NSMutableArray arrayWithCapacity:0];
}
return datahandle;
}
- (void)addPerson:(Person *)person {
汉字转拼音
NSMutableString *mutableString = [NSMutableString stringWithString:person.name];
CFStringTransform((CFMutableStringRef)mutableString, NULL, kCFStringTransformToLatin, false);
mutableString = (NSMutableString *)[mutableString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
获取首字母, 并且转成大写
NSString *firstLetter = [[mutableString substringToIndex:1] uppercaseString];
if ([firstLetter compare:@"A"] == -1 || [firstLetter compare:@"Z"] == 1) {
firstLetter = @"#";
}
通过首字母从字典中找对应的数组
NSMutableArray *array = [_personDic objectForKey:firstLetter];
if (array == nil) {
数组是不存在的
创建数组
array = [NSMutableArray arrayWithCapacity:1];
把person添加到数组中
[array addObject:person];
[_personDic setObject:array forKey:firstLetter];
} else {
数组已经存在
直接把person添加到数组中
[array addObject:person];
}
NSLog(@"%@", [self.personDic allKeys]);
// _titleArray = [[_personDic allKeys] mutableCopy];
}
重写getter方法, 为titleArray赋值
- (NSMutableArray *)titleArray {
排序: 冒泡排序, 提供两个各元素的比较方法, 提供相邻两个元素的比较规则
NSArray *sortArray = [self.personDic.allKeys sortedArrayUsingSelector:@selector(compare:)];
self.titleArray = [[sortArray mutableCopy] autorelease];
// NSLog(@"%@", self.titleArray);
return _titleArray;
}
- (BOOL)deletePersonWithIndexPath:(NSIndexPath *)indexpath {
当你重写getter方法以后, 使用变量是, 使用self
分区标题
NSString *key = self.titleArray[indexpath.section];
获取标题对应的数组
NSMutableArray *array = _personDic[key];
判断数组中是否只有一个元素
if (array.count == 1) {
一个元素, 删除键值对
[self.personDic removeObjectForKey:key];
return YES;
} else {
多个元素, 删除数组中的某个元素
[array removeObjectAtIndex:indexpath.row];
return NO;
}
}
- (void)movePersonAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
标题对应的数组
NSMutableArray *array = self.personDic[self.titleArray[sourceIndexPath.section]];
保留原来的数据
Person *person = [array[sourceIndexPath.section] retain];
移除数组中的数据
[array removeObject:person];
插入到数组的某个位置
[array insertObject:person atIndex:destinationIndexPath.row];
释放
[person release];
}
@end
UITableView综合 通讯录实战
原文:http://www.cnblogs.com/OrangesChen/p/4934250.html