主要實現三個功能:顯示備忘錄,新建備忘錄,備忘錄的詳細信息(可以顯示圖片)



這個備忘錄程序是一個很簡單的小項目,不過里邊包含了不少重要的知識,如TableView的用法,文本、圖片的保存等。
新建“Empty Application” ,命名為MemorandumBook
新建三個UIViewController視圖,分別命名為HomeViewController,AddViewController,DetailsViewController。三個視圖分別來實現對應的三個功能。
1.在AppDelegate.m中添加代碼:
(1)添加導航控制器
(2) 將homeViewController添加到導航器
(3) 將導航器添加到啟動的主視圖
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
navigationController = [[UINavigationController alloc] init];
HomeViewController *homeViewController = [[HomeViewController alloc] init];
homeViewController.title = @" 備忘錄 ";
[navigationController pushViewController:homeViewController animated:NO];//壓入棧
[self.window addSubview:navigationController.view];
[homeViewController release];
[self.window makeKeyAndVisible];
return YES;
}
2.
下面在HomeViewController視圖,來實現上圖的效果:
添加一個data.plist,存放備忘錄
在該視圖上添加一個TableView, 在HomeViewController上添加 NSMutableArray *booksArray 存放備忘錄信息,添加 - (void)initData方法,來讀取plist中的數據
// HomeViewController.h
#import <UIKit/UIKit.h>
@interface HomeViewController : UIViewController
@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, retain) NSMutableArray *booksArray;
- ( void)initData;
- ( void)didFinishAddingNewBook:(NSDictionary *)theBook;
@end
// HomeViewController.m
#import " HomeViewController.h "
#import " AddBookViewController.h "
#import " DetailsViewController.h "
@interface HomeViewController ()
@end
@implementation HomeViewController
@synthesize tableView;
@synthesize booksArray;
// 數據顯示到主視圖中
- ( void)initData
{
// 讀取data.plist數據
NSString *filePath = [[NSBundle mainBundle]pathForResource: @" data " ofType: @" plist "];
booksArray = [[NSMutableArray alloc]initWithContentsOfFile:filePath];
}
- ( void)viewDidLoad
{
[super viewDidLoad];
// 數據保存
/* booksArray是程序的數據源,在開發的時候,從data.plist中讀出數據賦值給它。在程序結束之前,所有的更改都需要被保存到data.plist中去。要做到這點,可以讓BookTableViewController在“感知”到程序快要結束時保存數據 */
// 為對象添加一個“觀察者”
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:app];
[self initData]; // 顯示數據
// 左Bar
UIBarButtonItem *leftBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editAction:)] autorelease];
self.navigationItem.leftBarButtonItem = leftBarBtn;
// 右Bar
UIBarButtonItem *rightBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAction:)] autorelease];
self.navigationItem.rightBarButtonItem = rightBarBtn;
// self.view.backgroundColor =[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];
// 設置背景
CGRect frame = self.view.bounds;
UIImageView *bg = [[UIImageView alloc] initWithFrame:frame];
bg.image = [UIImage imageNamed: @" bg.png "];
[self.view addSubview:bg];
[bg release];
self.tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain];
self.tableView. delegate = self;
self.tableView.dataSource = self;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
[self.view addSubview:self.tableView];
}
- ( void)addAction:( id)sender
{
// 導航到添加視圖
AddBookViewController *addBookViewController = [[AddBookViewController alloc] init];
addBookViewController. delegate = self; // 添加完成后回調到本視圖(BookViewController)的方法
[self.navigationController pushViewController:addBookViewController animated:YES];
[addBookViewController release];
}
- ( void)editAction:( id)sender
{
[self.tableView setEditing:YES animated:YES];
UIBarButtonItem *leftBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneAction:)] autorelease];
self.navigationItem.leftBarButtonItem = leftBarBtn;
}
// 又把視圖的編輯轉態改了回去,同時也把左按鈕改了回去。
- ( void)doneAction:( id)sender
{
[self.tableView setEditing:NO animated:YES];
UIBarButtonItem *leftBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editAction:)] autorelease];
self.navigationItem.leftBarButtonItem = leftBarBtn;
}
// 表視圖的委托方法
// 指定單元格的個數
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [booksArray count];
}
// 單元格對象
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @" Cell ";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [[booksArray objectAtIndex:indexPath.row] valueForKey: @" Text "];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; // 單元格右邊的顯示為一個箭頭,用以提示用戶點擊后展開
return cell;
}
// 選中某行
- ( void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailsViewController *detailsViewController = [[DetailsViewController alloc] init];
detailsViewController.bookDictionary = [booksArray objectAtIndex:indexPath.row]; // 將選中的值傳遞到詳細視圖頁
[self.navigationController pushViewController:detailsViewController animated:YES]; // 導航到詳細視圖
[detailsViewController release];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
// 編輯,刪除
- ( void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// 從數據源中刪除該行
// 刪除圖片
NSString *filePath = [[booksArray objectAtIndex:indexPath.row] valueForKey: @" Image "];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
[booksArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
// 創建相應類的實例,插入到數組中,並且向表中增加一行
}
}
- ( void)didFinishAddingNewBook:(NSDictionary *)theBook
{
[booksArray addObject:theBook];
[self.tableView reloadData];
}
- ( void)viewDidUnload
{
[super viewDidUnload];
}
// 程序快要結束時調用
- ( void)applicationWillTerminate:(UIApplication *)application
{
NSString *path = [[NSBundle mainBundle] pathForResource: @" data " ofType: @" plist "]; // 找到文件路徑
[booksArray writeToFile:path atomically:YES]; // 寫入
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- ( void)dealloc {
[tableView release];
[super dealloc];
}
@end
3.

下面來實現AddViewController視圖:
在xib上添加ImageView,Label,2個Button,如上圖布局。
Button“添加文本”的方法:
用到UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIActionSheetDelegate 等協議
UIBarButtonItem *rightBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneEditing:)] autorelease];
self.navigationItem.rightBarButtonItem = rightBarBtn;
textView = [[UITextView alloc] initWithFrame:CGRectMake( 0, - 240, 320, 240)];
textView.text = textLabel.text;
[self.view addSubview:textView];
[UIView beginAnimations: @" pushAnimation " context:textView];
[UIView setAnimationCurve: 0.2];
[textView setFrame:CGRectMake( 0, 0, 320, 240)];
[UIView commitAnimations];
[textView becomeFirstResponder];
}
// 完成編輯
- ( void)doneEditing:( id)sender
{
// textView彈回,取消其第一響應者身份(鍵盤彈回)
[textView resignFirstResponder];
[UIView beginAnimations: @" popAnimation " context:textView];
[UIView setAnimationDuration: 0.2];
[textView setFrame:CGRectMake( 0, - 240, 320, 240)];
[UIView commitAnimations];
[textLabel setText:textView.text];
// 右bar恢復“done”
UIBarButtonItem *rightBarBtn = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(doneAction:)] autorelease];
self.navigationItem.rightBarButtonItem = rightBarBtn;
}
Button“添加圖片”的方法:
cancelButtonTitle: @" 取消 "
destructiveButtonTitle: @" 拍照 "
otherButtonTitles: @" 選擇照片 ", nil];
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
}
// UIImagePickerControllerDelegate的委托方法
- ( void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
image = [info objectForKey:UIImagePickerControllerEditedImage];
[imageView setImage:image];
[picker dismissModalViewControllerAnimated:YES];
}
- ( void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissModalViewControllerAnimated:YES];
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
}
- ( void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
UIImagePickerController *imagePicker = [[[UIImagePickerController alloc] init] autorelease];
imagePicker.allowsImageEditing = YES;
if (buttonIndex == 0)
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
// imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @" 沒有相機 "
message:nil
delegate:nil
cancelButtonTitle: @" 關閉 "
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
}
else if (buttonIndex == 1)
{
// imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
else if (buttonIndex == 2)
{
return;
}
imagePicker. delegate = self;
[self presentModalViewController:imagePicker animated:YES];
}
- ( void)doneAction:( id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *filePath = [paths objectAtIndex: 0];
NSString *fileName = [NSString stringWithFormat: @" %d.png ",random()];
filePath = [filePath stringByAppendingPathComponent:fileName];
// NSData *imageData = UIImageJPEGRepresentation(image,1.0f); // 取1.0代表最佳品質
NSData *imageData = UIImagePNGRepresentation(image); // 取1.0代表最佳品質
if (imageData)
{
[[NSFileManager defaultManager] createFileAtPath:filePath contents:imageData attributes:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message: @" 請選擇照片 "
delegate:nil
cancelButtonTitle: @" 確認 "
otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
if ([textLabel.text isEqualToString: @""])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message: @" 請輸入備忘 " delegate:nil cancelButtonTitle: @" 確認 " otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSDictionary *newBook = [[NSDictionary alloc] initWithObjectsAndKeys:textLabel.text, @" Text ", filePath, @" Image ", nil];
[ delegate performSelector:@selector(didFinishAddingNewBook:) withObject:newBook];
[self.navigationController popViewControllerAnimated:YES];
}
4.
下面來實現DetailsViewController視圖:
這個只需要將文本和圖片讀出來,所以比較簡單
// DetailsViewController.m
#import " DetailsViewController.h "
@interface DetailsViewController ()
@end
@implementation DetailsViewController
@synthesize imageView;
@synthesize textView;
@synthesize bookDictionary;
- ( void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = @" 詳細信息 ";
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[bookDictionary valueForKey: @" Image "]];
if (image)
{
[imageView setImage:image];
}
[image release];
textView.text = [bookDictionary valueForKey: @" Text "];
}
- ( void)viewDidUnload
{
[self setTextView:nil];
[self setImageView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- ( void)dealloc {
[textView release];
[imageView release];
[super dealloc];
}
@end