Click here...
Trong phần cuối này, chúng ta sẽ học những chi tiết hơn xung quanh Core Data và xử lý những thao tác CRUD trên data model của bạn. Trong post này, chúng ta sẽ tập trung trên UI, hay giao diện người dùng, lớp này nằm phía trên của view controllers mà nó cho phép một người tương tác với dữ liệu của chúng ta.
Trong phần cuối này, chúng ta sẽ học những chi tiết hơn xung quanh Core Data và xử lý những thao tác CRUD trên data model của bạn. Trong post này, chúng ta sẽ tập trung trên UI, hay giao diện người dùng, lớp này nằm phía trên của view controllers mà nó cho phép một người tương tác với dữ liệu của chúng ta.
Tạo một storyboard
Đầu tiên, chúng ta sẽ cần thêm một
storyboard đến dự án của chúng ta. Ấn command + N và chọn “User Interface” từ
mẫu hiện có. Chọn Storyboard và click next.
Đặt tên file là “MainStoryboard” và
click create. Trong dự án MusicLabel, target select the storyboard we just
created to be the Main Storyboard.
Tạo một tableview
Click storyboard và chắc chắn rằng
pane “Utilities” được mở.
Kéo một table view controller từ thư
viện đối tượng trong storyboard.
With the prototype cell selected,
navigate to the attributes inspector. Enter “Cell” as an identifier.
Nhấn command + N, và từ những mẫu
“Cocoa touch”, chọn lớp “Objective-C”.
Đặt tên file
“MLBLLabelViewController” và subclass của UITableViewController.
Back in the storyboard, select the
table view controller and navigate to the identity inspector. Thay đổi custom
class thành “MLBLLabelViewController”.
Thay đổi một số cái trong
MLBLLabelViewController.h:
#import <UIKit/UIKit.h>
#import "MLBLAppDelegate.h"
#import "Label.h"
@interface MLBLLabelViewController : UITableViewController
// An array to house all of our fetched Label objects
@property (strong, nonatomic) NSArray *labelArray;
@end
|
Thay đổi file
MLBLLabelViewController.m:
/* Make these changes to MLBLLabelViewController.M */
@implementation MLBLLabelViewController
@synthesize labelArray;
- (void) viewWillAppear:(BOOL)animated {
[super
viewWillAppear:animated];
/* Here we call
the method to load the table data */
[self
loadTableData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView
{
// We only need
to return 1 for this table view
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// We'll return
the count of the objects in labelArray
return
[labelArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString
*CellIdentifier = @"Cell";
UITableViewCell
*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
if (cell == nil)
{
cell =
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the
cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Grab the
label
Label *label =
[self.labelArray objectAtIndex:indexPath.row];
// Set the text of the cell to the label
name
cell.textLabel.text = label.name;
return cell;
}
#pragma mark - Private methods
- (MLBLAppDelegate *)appDelegate {
return
(MLBLAppDelegate *)[[UIApplication sharedApplication] delegate];
}
// This method executes a fetch request and reloads the
table view.
- (void) loadTableData {
NSManagedObjectContext *context = [[self appDelegate]
managedObjectContext];
// Construct a
fetch request
NSFetchRequest
*fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Label"
inManagedObjectContext:context];
[fetchRequest
setEntity:entity];
// Add an
NSSortDescriptor to sort the labels alphabetically
NSSortDescriptor
*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
NSArray
*sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest
setSortDescriptors:sortDescriptors];
NSError *error =
nil;
self.labelArray
= [context executeFetchRequest:fetchRequest error:&error];
[self.tableView
reloadData];
}
@end
|
Build và chạy. Dựa vào dữ liệu chúng
ta nhập vào ở bài hướng dẫn cuối này, bàn nên nhìn thấy như sau:
Tạo một Navigation Controller
Bây giờ hãy thêm cho thiết lập của
chúng ta: với “MLBLLabelViewController” được chọn trong storyboard, chọn
Editor>Embed In>Navigation Controller. Một navigation controller là một
chuẩn UI được cung cấp bởi Apple để hướng luồng đi của ứng dụng. Nó bao gồm
logic cho việc quay lại view controller trước cũng như giao tiếp giữa các màn
hình với nhau. Chúng ta tạo “MLBLLabelViewController” như là root view controller
trong navigation controller của chúng ta.
Drag another table view controller
onto the storyboard. Create a new file “MLBLArtistViewController” that
subclasses UITableViewController. Change the custom class of the new table view
controller to “MLBLArtistViewController”. Give it a storyboard ID of
“ArtistViewController”
Kéo table view khác vào trong
storyboard. Tạo một file mới “MLBLArtistViewController” mà subclass của
UITableViewController. Thay đổi custom class của table view mới này thành “MLBLArtistViewController”. Cho nó một storyboard ID của “ArtistViewController”.
Thay đổi trong file MLBLArtistViewController.h:
#import <UIKit/UIKit.h>
#import "MLBLAppDelegate.h"
#import "Label.h"
#import "Artist.h"
@interface MLBLArtistViewController :
UITableViewController
// An array to house all of our fetched Artist objects
@property (strong, nonatomic) NSArray *artistArray;
//The id of the parent object
@property (strong, nonatomic) NSManagedObjectID *labelID;
@end
|
Thay đổi trong file MLBLArtistViewController.m:
/* Make these changes to MLBArtistViewController.m */
@implementation MLBLArtistViewController
@synthesize artistArray;
-(void)viewWillAppear:(BOOL)animated {
[super
viewWillAppear:animated];
[self
loadTableData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView
*)tableView
{
// We only need
to return 1 for this table view
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// We'll return
the count of the objects in artistArray
return
[artistArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString
*CellIdentifier = @"Cell";
UITableViewCell
*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
if (cell == nil)
{
cell =
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the
cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Grab the
artist
Artist *artist =
[self.artistArray objectAtIndex:indexPath.row];
cell.textLabel.text = artist.name;
return cell;
}
#pragma mark - Private methods
- (MLBLAppDelegate *)appDelegate {
return
(MLBLAppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) loadTableData {
NSManagedObjectContext *context = [[self appDelegate] managedObjectContext];
// Construct a
fetch request
NSFetchRequest
*fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Artist"
inManagedObjectContext:context];
[fetchRequest
setEntity:entity];
NSPredicate
*predicate = [NSPredicate predicateWithFormat:@"label == %@",
[context objectWithID:self.labelID]];
[fetchRequest
setPredicate:predicate];
// Add an
NSSortDescriptor to sort the labels alphabetically
NSSortDescriptor
*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
NSArray
*sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest
setSortDescriptors:sortDescriptors];
NSError *error =
nil;
self.artistArray
= [context executeFetchRequest:fetchRequest error:&error];
[self.tableView
reloadData];
}
@end
|
#import MLBLArtistViewController.h to the MLBLLabelViewController.m file. In the - (void)tableView:(UITableView
*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method, make the following changes:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MLBLArtistViewController *artistViewController = [self.storyboard
instantiateViewControllerWithIdentifier:@"ArtistViewController"];
// Grab the
label
Label *label =
[self.labelArray objectAtIndex:indexPath.row];
artistViewController.labelID = [label objectID];
[self.navigationController pushViewController:artistViewController
animated:YES];
}
|
Build và chạy, và bạn nên có thể xem
những artists mà nó liên quan đến một label.
Tiếp theo, làm tương tự với albums.
Tạo một file gọi là “MLBLAlbumViewController” mà subclass là
UITableViewController, và lặp những bước này cho “MLBLArtistViewController”.
Tạo một Input View
Bây giờ chúng ta tạo một màn hình
input để chèn dữ liệu vào trong database của chúng ta. Thêm 2 dòng code sau đến
-(void)viewDidLoad method in MLBLLabelViewController.m:
UIBarButtonItem
*item = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self
action:@selector(addItem)];
self.navigationItem.rightBarButtonItem
= item;
Tạo một file gọi là “MLBLLabelEntryViewController”,
mà subclass là UIViewController. Kéo một view controller từ thư việc đối tượng
vào trong storyboard. Thay đổi custom class đến “MLBLLabelEntryViewController”.
Kéo một text field vào trong view controller. Trong những attributs inspector
bạn có thể customize text field; thiết lập placeholder (chữ mờ) là “Enter the
Label Name”.
Giữ option key và lick vào MLBLLabelEntryViewController.h.
Cái này sẽ mở file bên cạnh storyboard.
Giữ control key, click vào text
field đầu tiên và kéo dòng màu xanh đến tệp MLBLLabelEntryViewController.h.
Điều này sẽ thiết lập một outlet
connection giữa các storyboard nib file và view controller class. Đặt tên
outlet “labelField” và click connect.
Thêm những code sau đến
MLBLLabelEntryViewController.m:
/* Make these changes to
MLBLLabelEntryViewController.m */
#import "MLBLLabelEntryViewController.h"
#import "MLBLAppDelegate.h"
#import "Label.h"
@implementation MLBLLabelEntryViewController
- (void)viewDidLoad
{
[super
viewDidLoad];
// Do any
additional setup after loading the view.
// This will
call our
UIBarButtonItem
*item = [[UIBarButtonItem alloc] initWithTitle:@"Add"
style:UIBarButtonItemStyleBordered target:self action:@selector(addLabel)];
self.navigationItem.rightBarButtonItem = item;
UIBarButtonItem
*item2 = [[UIBarButtonItem alloc] initWithTitle:@"Cancel"
style:UIBarButtonItemStyleBordered target:self action:@selector(dismiss)];
self.navigationItem.leftBarButtonItem = item2;
}
#pragma mark - private methods
- (MLBLAppDelegate *)appDelegate {
return
(MLBLAppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) addLabel {
// Grab the
context
NSManagedObjectContext *context = [[self appDelegate]
managedObjectContext];
// Grab the
Label entity
Label *label =
[NSEntityDescription insertNewObjectForEntityForName:@"Label"
inManagedObjectContext:context];
// Set label
name
label.name =
self.labelField.text;
// Save
everything
NSError *error =
nil;
if ([context
save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The save wasn't successful: %@", [error userInfo]);
}
[self dismiss];
}
- (void) dismiss {
[self
dismissViewControllerAnimated:YES completion:nil];
}
@end
|
Trong tệp MLBLLabelViewController.m,
thêm #import
"MLBLLabelEntryViewController.h", thêm
code sau vào:
// Add this method for slide to delete
-(UITableViewCellEditingStyle)tableView:(UITableView
*)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return
UITableViewCellEditingStyleDelete;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle
== UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSManagedObjectContext *context = [[self appDelegate]
managedObjectContext];
// Grab the
label
Label *label
= [self.labelArray objectAtIndex:indexPath.row];
[context deleteObject:[context
objectWithID:[label objectID]]];
// Save
everything
NSError
*error = nil;
if ([context
save:&error]) {
NSLog(@"The save was successful!");
} else {
NSLog(@"The
save wasn't successful: %@", [error userInfo]);
}
NSMutableArray *array = [self.labelArray mutableCopy];
[array
removeObjectAtIndex:indexPath.row];
self.labelArray = array;
[tableView
deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
// Add this method under our private methods pragma mark
- (void) addItem {
MLBLLabelEntryViewController *labelEntryViewController =
[self.storyboard instantiateViewControllerWithIdentifier:@"LabelEntryViewController"];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:labelEntryViewController];
[self
presentViewController:navigationController animated:YES completion:nil];
}
|
Build và chạy, bạn có thể add Labels
đến cơ sở dữ liệu. Bạn cũng có thể slide để xóa Labels từ table, và remove
chúng từ database. Bạn có thể dễ dàng mở rộng điều này bằng cách thêm input
views cho Artists và Albums.
Source: https://blog.stackmob.com/2012/11/iphone-database-tutorial-part-1-learning-core-data/
No comments:
Post a Comment