update: 2011/12/02
參考資料:
1. iPhone Development – core data search criteria tutorial
2. iPhone Development – core data search criteria tutorial part 2
A. 之前, 在 Lala's Program Note 實作記錄: 2.標籤列架構, 中的 G. 增加 Search(搜尋)
頁籤, 已新增了 SearchViewController, 現在開始手動加入 UI 元件:
1. 修改 SearchViewController.h 檔案如下:
#import <UIKit/UIKit.h>
//@add
#import <CoreData/CoreData.h>
@interface SearchViewController : UIViewController {
//@add
UISearchBar *mySearchBar;
UISegmentedControl *mySegmentedControl;
UITableView *myTableView;
}
//@add
@property (nonatomic, retain) UISearchBar *mySearchBar;
@property (nonatomic, retain) UISegmentedControl *mySegmentedControl;
@property (nonatomic, retain) UITableView *myTableView;
@end
----------------------------------------------------------------------------------------------------------
2. 修改 SearchViewController.m 檔案如下:
@synthesize mySearchBar, mySegmentedControl, myTableView;
//@add
- (void)dealloc
{
[mySearchBar release];
[mySegmentedControl release];
[myTableView release];
[super dealloc];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//@add
// screen resolution: iPhone 320x480 ; iPhone4 640x960
/* mySearchBar */
mySearchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,0,320,40)];
[self.view addSubview:mySearchBar];
[mySearchBar release];
/* mySegmentedControl */
mySegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"All", @"Title", @"Content", nil]];
[mySegmentedControl setFrame:CGRectMake(5,45,310,35)];
mySegmentedControl.selectedSegmentIndex = 0;
[self.view addSubview:mySegmentedControl];
[mySegmentedControl release];
/* myTableView */
myTableView = [[UITableView alloc] init];
[myTableView setFrame:CGRectMake(0,85,320,400)];
[self.view addSubview:myTableView];
[myTableView release];
}
----------------------------------------------------------------------------------------------------------
3. 完成的 UI 如下所示:
1. Select NoteBook entity in the model editor.
> File > New > New File > Core Data > NSManagedObject subclass >
Next
說明: 產生 NoteBook.h 與 NoteBook.m 檔案
2. Select NoteArticle entity in the model editor.
> File > New > New File > Core Data > NSManagedObject subclass >
Next
說明: 產生 NoteArticle.h 與 NoteArticle.m 檔案
C. 增加相關的 protocol 與 search 的處理
1. 修改 SearchViewController.h 檔案如下:
//@interface SearchViewController : UIViewController {
@interface SearchViewController : UIViewController <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource> {
//@add
UISearchBar *mySearchBar;
UISegmentedControl *mySegmentedControl;
UITableView *myTableView;
//@add
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
//@add
NSMutableString *searchCriteria; // to hold search criteria
NSArray *fetchedObjects; // to hold search results
}
//@add
@property (nonatomic, retain) UISearchBar *mySearchBar;
@property (nonatomic, retain) UISegmentedControl *mySegmentedControl;
@property (nonatomic, retain) UITableView *myTableView;
//@add
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
//@add
- (IBAction)segmentedControlChanged;
// We have conform UISearchBarDelegate protocol, so it will auto triger this method
- (void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar;
@end
----------------------------------------------------------------------------------------------------------
2. 修改 SearchViewController.m 檔案如下:
#import "SearchViewController.h"
//@add
#import "NoteBook.h"
#import "NoteArticle.h"
//add
#import "ArticleViewController.h"
@implementation SearchViewController
//@add
@synthesize mySearchBar, mySegmentedControl, myTableView;
@synthesize managedObjectContext, fetchedResultsController;
//@add
- (void)dealloc
{
[mySearchBar release];
[mySegmentedControl release];
[myTableView release];
//@update
[managedObjectContext release];
[fetchedResultsController release];
[searchCriteria release];
[super dealloc];
}
//@add
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar
{
NSLog(@"searchBarSearchButtonClicked with searchCriteria = %@", searchCriteria);
NSError *error = nil;
// We use an NSPredicate combined with the fetchedResultsController to perform the search
// * the [cd] bit specifies a case & diacritic insensitive search (不分大小寫)
if (self.mySearchBar.text !=nil)
{
// search for all article (both title & content)
if ([searchCriteria isEqualToString:@"all"])
{
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"title contains[cd] %@ OR content contains[cd] %@", self.mySearchBar.text, self.mySearchBar.text];
[fetchedResultsController.fetchRequest setPredicate:predicate];
}
// search for article's title
else if ([searchCriteria isEqualToString:@"title"])
{
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"title contains[cd] %@", self.mySearchBar.text];
[fetchedResultsController.fetchRequest setPredicate:predicate];
}
// search for article's content
else if ([searchCriteria isEqualToString:@"content"])
{
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"content contains[cd] %@", self.mySearchBar.text];
[fetchedResultsController.fetchRequest setPredicate:predicate];
}
}
else
{
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"];
[fetchedResultsController.fetchRequest setPredicate:predicate];
}
if (![[self fetchedResultsController] performFetch:&error])
{
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
// this array is just used to tell the table view how many rows to show
fetchedObjects = fetchedResultsController.fetchedObjects;
// dismiss the search keyboard
[mySearchBar resignFirstResponder];
// reload the table view
[myTableView reloadData];
}
//@add
- (IBAction)segmentedControlChanged
{
switch (mySegmentedControl.selectedSegmentIndex)
{
case 0:
[searchCriteria setString:@"all"];
return;
case 1:
[searchCriteria setString:@"title"];
return;
case 2:
[searchCriteria setString:@"content"];
return;
}
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//@add
// screen resolution: iPhone 320x480 ; iPhone4 640x960
/* mySearchBar */
mySearchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,0,320,40)];
//@add
mySearchBar.delegate = self;
//mySearchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:mySearchBar];
[mySearchBar release];
/* mySegmentedControl */
mySegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"All", @"Title", @"Content", nil]];
[mySegmentedControl setFrame:CGRectMake(5,45,310,35)];
mySegmentedControl.selectedSegmentIndex = 0;
//@add
[mySegmentedControl addTarget:self action:@selector(segmentedControlChanged) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mySegmentedControl];
[mySegmentedControl release];
/* myTableView */
myTableView = [[UITableView alloc] init];
[myTableView setFrame:CGRectMake(0,85,320,400)];
//@add
myTableView.delegate = self;
myTableView.dataSource = self;
[self.view addSubview:myTableView];
[myTableView release];
//@add
//initializing our searchCriteria NSString
searchCriteria = [[NSMutableString alloc] initWithString:@"title"];
// NSFetchRequest needed by the fetchedResultsController
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// NSSortDescriptor tells defines how to sort the fetched results
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// fetchRequest needs to know what entity to fetch
NSEntityDescription *entity = [NSEntityDescription entityForName:@"NoteArticle" inManagedObjectContext:managedObjectContext];
[fetchRequest setFetchBatchSize:10];
[fetchRequest setEntity:entity];
[sortDescriptor release];
[sortDescriptors release];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"SearchArticles"];
[fetchRequest release];
}
#pragma mark Table view Methods
#pragma mark Table view data source
//@add
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count]; //return 1;
}
//@add
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//id<NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
//return [sectionInfo numberOfObjects];
return [fetchedObjects count];
}
//@add
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"SearchCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease];
}
// customize cell
NoteArticle *noteArticle = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSMutableString *cellTitle = [[[NSMutableString alloc] init] autorelease];
[cellTitle appendString:noteArticle.title];
cell.textLabel.text = cellTitle;
cell.textLabel.textColor = [UIColor brownColor];
NSMutableString *cellSubTitle = [[[NSMutableString alloc] init] autorelease];
[cellSubTitle appendString:noteArticle.subTitle];
cell.detailTextLabel.text = cellSubTitle;
cell.detailTextLabel.textColor = [UIColor darkGrayColor];
return cell;
}
//@add
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ArticleViewController *articleViewController = [[ArticleViewController alloc] init];
NSManagedObject *article = [self.fetchedResultsController objectAtIndexPath:indexPath];
articleViewController.article = article;
// relationship
articleViewController.title = [[article valueForKey:@"notebook"] valueForKey:@"name"];
[self.navigationController pushViewController:articleViewController animated:YES];
[articleViewController release];
}
@end
----------------------------------------------------------------------------------------------------------
3. 修改 Lala_s_Program_NoteAppDelegate.m 檔案如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
/* C. for SearchViewController */
// 1. Create a instance of SearchViewController
SearchViewController *searchViewController = [[SearchViewController alloc] init];
// 2. set controller's managed object context member right after initializing
//@add
searchViewController.managedObjectContext = self.managedObjectContext;
....
}D. 結果:
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。