UITableView Search Controller & Heading Titles (iPhone OS 3.1)

+More of a continuation from a previous thread to discuss a more specific issue+
→ Ray,
I could never get the Sections project to work. I had checked the code, but it still didn't load.
I had tried taking some code out of the book. The initial problems came in the fact that the book used an NSDictionary, and some dictionary specific code, whereas I'm using an array.
In addition, I had taken some code out of Apple's TableSearch sample project, which, among other things, uses a UISearchDisplayController, which is different from the Sections project.
Basically, for the section headings I'm just interested in grabbing the first character in the person object's name, matching it against existing NSStrings in an array, and if it's a different letter, then adding it to the array. The end result should be similar to the built-in Contacts application, assuming that you don't have a contact for every single letter of the alphabet.
I don't want an index, as that would interfere with the detail disclosure buttons (as per the HIG).
Finally, the table is implemented so that it loads a second view based on an objectAtIndex of indexPath.row. The only issue is that when searching it still references the initial array, and so it displays the wrong second level control. I was thinking of implementing a flag which I could check in tableView:didSelectRowAtIndexPath, but I don't know of any isSearching method or equivalent. As before, I'm using a Search Display Controller instead of merely a search bar, which is what the Sections project uses.
Message was edited by: musicwind95

Ok, here's an edit of your EmployeeViewController class that shows how to implement section headers (Person.m is also included to correct a couple minor memory management problems I noticed, but those have nothing to do with our main topic):
// EmployeesViewController.h
#import <UIKit/UIKit.h>
@interface EmployeesViewController : UITableViewController <UISearchDisplayDelegate, UISearchBarDelegate> {
NSArray *initArray; // <-- added master data array
NSDictionary *listContent; // Master data content <-- changed to dictionary
NSDictionary *filteredListContent; // Filtered content as a result of a search <-- changed to dictionary
// The saved state of the search in case of a memory warning
NSString *savedSearchTerm;
BOOL searchWasActive;
BOOL searchIsActive;
// NSString *employeeName;
@property (nonatomic, retain) NSArray *initArray; // <-- added master data array
@property (nonatomic, retain) NSDictionary *listContent; // <-- changed to dictionary
@property (nonatomic, retain) NSDictionary *filteredListContent; // <-- changed to dictionary
@property (nonatomic, copy) NSString *savedSearchTerm;
@property (nonatomic) BOOL searchWasActive;
@property (nonatomic) BOOL searchIsActive;
@end
// EmployeesViewController.m
#import "EmployeesViewController.h"
// #import "NSDictionary-MutableDeepCopy.h" <-- not needed
#import "Person.h"
// #import "Constants.h" <-- not needed
#import "EmployeesDetailController.h"
// #import "EmployeeJobsController.h" <-- not needed
@implementation EmployeesViewController
@synthesize initArray; // <-- added master data array
@synthesize listContent;
@synthesize filteredListContent;
@synthesize savedSearchTerm;
@synthesize searchWasActive;
@synthesize searchIsActive;
#pragma mark -
#pragma mark Custom Methods
// --> added helper method to handle openURL:tel: failure
- (void)openTelURLFailed:(Person*)person {
NSString *device = [UIDevice currentDevice].model;
NSLog(@"Call could not be successfully opened. This device is an %@", device);
// TODO: Does this message comply with HIG? If user can't do anything, why display the alert?
// --> It's correct to let the user know why the call failed and ask the user to acknowledge this
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Could not open Phone application"
message:[NSString stringWithFormat:
@"The phone call to %@
could not be placed because your %@ does not have a Phone application.",
[person employeeName], [person telephoneNumber], device]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
// --> added helper method to make alphabetic dictionary from sorted array of Person objects
- (NSDictionary)getDictionaryFromArray:(NSArray)personArray {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:26];
for (Person *p in personArray) {
// get the first initial of employeeName as an uppercase string
NSString *name = [p.employeeName capitalizedString];
if (![name length]) continue;
NSString *initial = [name substringToIndex:1];
NSMutableArray *array = [dict objectForKey:initial];
if (array == nil) {
// add new key-array pair to the dictionary
array = [NSMutableArray arrayWithCapacity:[personArray count]];
[dict setObject:array forKey:initial];
// add current Person object to the array for first initial of name
[array addObject:p];
return [NSDictionary dictionaryWithDictionary:dict];
// --> added helper method to get the array of Person objects for a given table and section no.
- (NSArray)getListForTableView:(UITableView)tableView section:(NSUInteger)section {
NSDictionary *dict = tableView == self.searchDisplayController.searchResultsTableView ? filteredListContent : listContent;
NSString *key = [[[dict allKeys] sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:section];
return [dict objectForKey:key];
#pragma mark -
#pragma mark Lifecycle Methods
- (void)viewDidLoad {
// Create dummy data set --> start abbreviated code block
NSArray *jobs = [[NSArray alloc] initWithObjects: // ...
NSArray *alex = [[NSArray alloc] initWithObjects: // ...
NSArray *turner = [[NSArray alloc] initWithObjects: // ...
NSArray *initContents = [[NSArray alloc] initWithObjects:
[Person personWithContentsOfArray:alex],
[Person personWithContentsOfArray:turner],
nil];
self.initArray = initContents; // <-- save master data array
self.listContent = [self getDictionaryFromArray:initArray]; // <-- dictionary
[alex release];
[turner release];
// --> end abbreviated code block - all other code in this file may be copied verbatim
[jobs release];
[initContents release];
// Create a filtered list that will contain products for the search results table <-- not needed here
// Restore search settings if previously saved
if (self.savedSearchTerm){
[self.searchDisplayController setActive:self.searchWasActive];
[self.searchDisplayController.searchBar setText:savedSearchTerm];
self.savedSearchTerm = nil;
[self.tableView reloadData];
self.tableView.scrollEnabled = YES;
self.searchIsActive = NO;
- (void)viewDidUnload {
self.filteredListContent = nil;
self.searchIsActive = NO;
- (void)viewDidDisappear:(BOOL)animated {
// Save the state of the search
self.searchWasActive = [self.searchDisplayController isActive];
self.savedSearchTerm = [self.searchDisplayController.searchBar text];
self.searchIsActive = NO;
- (void)dealloc {
[savedSearchTerm release]; // <-- release retained string
[listContent release];
[filteredListContent release];
[initArray release]; // <-- release master data array
[super dealloc];
#pragma mark -
#pragma mark UITableView data source and delegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSDictionary *dict = tableView == self.searchDisplayController.searchResultsTableView ? filteredListContent : listContent; // <-- get dictionary
return [[dict allKeys] count]; // <-- return number of keys in dictionary
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// If the requested table view is the search controller's view, return the count of the filtered list; otherwise, return the count of the main list
NSArray *list = [self getListForTableView:tableView section:section]; // <-- get array for section
return [list count]; // <-- return row count for section
// --> added to implement section headers
- (NSString)tableView:(UITableView)tableView titleForHeaderInSection:(NSInteger)section {
NSDictionary *dict = tableView == self.searchDisplayController.searchResultsTableView ? filteredListContent : listContent;
NSArray *allKeys = [dict allKeys];
if ([allKeys count] == 0)
return @"";
return [[allKeys sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:section];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *kCellID = @"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID] autorelease];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
// If the requesting table view is the search controller's table, configure the cell using the filtered content; otherwise, use the main list
NSArray *list = [self getListForTableView:tableView section:indexPath.section]; // <-- get array for section
Person *person = [list objectAtIndex:indexPath.row]; // <-- get person for row
cell.textLabel.text = person.employeeName;
cell.detailTextLabel.text = person.telephoneNumber;
return cell;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog (@"searchIsActive: %d", self.searchIsActive); // <-- %d
// if (self.searchIsActive == NO) { // <-- = > -- }
// rewrite to consolidate code:
NSArray *list = [self getListForTableView:tableView section:indexPath.section]; // <-- get array for section
Person *person = [list objectAtIndex:indexPath.row];
NSString *phoneNumberToDial = [NSString stringWithFormat:@"tel:%@", [person telephoneNumber]];
NSURL *callURL = [[NSURL alloc] initWithString:phoneNumberToDial];
if ([[UIApplication sharedApplication] openURL:callURL])
NSLog(@"Call initialized properly.");
else
[self openTelURLFailed:person];
[callURL release];
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
NSArray *list = [self getListForTableView:tableView section:indexPath.section]; // <-- get array for section
EmployeesDetailController *detailView = [[EmployeesDetailController alloc] dataFromPerson:[list objectAtIndex:indexPath.row]]; // <--
[self.navigationController pushViewController:detailView animated:YES];
[detailView release]; // <-- uncomment
#pragma mark -
#pragma mark Content Filtering
- (void)filterContentForSearchText:(NSString *)searchText {
// Update the filtered array based on the search text and scope
// Clear the filtered array <-- the filtered array is now local
NSMutableArray *filteredArray = [NSMutableArray arrayWithCapacity:[self.initArray count]];
// Search the main list for products whose name matches searchText, and add matching items to the filtered array
for (Person *person in initArray) { // <-- traverse the master data array
NSComparisonResult resultName = [person.employeeName compare:searchText options:(NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
NSComparisonResult resultPhone = [person.telephoneNumber compare:searchText options:(NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (resultName == NSOrderedSame || resultPhone == NSOrderedSame) {
[filteredArray addObject:person];
self.filteredListContent = [self getDictionaryFromArray:filteredArray]; // <-- get filtered dictionary from filtered array
self.searchIsActive = YES;
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString];
self.searchIsActive = YES;
// Return YES to force the table view to be reloaded
return YES;
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
self.searchIsActive = YES;
@end
// Person.m
#import "Person.h"
@implementation Person
+(id)personWithContentsOfArray:(NSArray *)initArray {
Person *myPerson = [[[Person alloc] init] autorelease]; // <-- convenience method should autorelease
return myPerson;
- (void)dealloc { // <-- release all retained ivars
[employeeName release];
[telephoneNumber release];
[employeeEmail release];
[employeeJobs release];
[super dealloc];
@end
The above doesn't do anything about saving or retrieving persistent data. Instead of using the plist structure described previously, the example just converts your dummy array to a dictionary. I decided not to replace the dummy array with a more natural structure after giving some thought to where the overall app might be headed. Considering the Employee section in isolation, the plist is a natural fit. But the finance tab tells us you're probably going to need a database. If that's the case the dummy array might as well stay in place until we know more about the overall data requirements (I can only hope you haven't promised anyone a one-off iPhone port of QuickBooks for Father's Day).
- Ray

Similar Messages

  • Adf Mobile Header Title

    Hi,
    I'm developing and ADF Mobile App using JDev 11.1.2.4. Deploying to IPhone.
    I have an AMX page with a Title in the facet header and a command button as the primary action (back button).
    That button has a long text inside. It goes over the header title. I need that button to push the header title.
    Is there a way to do that with CSS or i need to control the size of the text inside the button?
    Thank you.

    Thanks for the reply!
    So, I have created a new file named myipad.css under styles folder in resources of Application Controller project with following contents:
    .amx-panelPage-header{
        height: 144px;
    And my adfmf-skins.xml looks like below:
    <?xml version="1.0" encoding="UTF-8" ?>
    <adfmf-skins xmlns="http://xmlns.oracle.com/adf/mf/skin">
    <skin id="s1">
            <id>mobileFusionFx.iPad</id>
            <family>mobileFusionFx</family>
            <extends>mobileFusionFx.iPad</extends>
           <style-sheet-name>styles/myipad.css</style-sheet-name>
        </skin>
    </adfmf-skins>
    However, on running the app looks like there is not effect of it. Please advise what is wrong here.

  • Will Aperture allow me to search photos by title on an iPad?

    Will Aperture allow me to search photos by title on an iPad? iPhoto library does not let me search for photos by name. Thanks for your help and any suggestions.  Rob

    Rob,
    as Frank Caggiano said. There is not really any Apple-provided application on the iPad that will support a full-fledged photo database like the Mac-versions of Aperture or iPhoto. Even the IOS app iPhoto is nothing like the Mac version of iPhoto. The iPad version is not a photo database but a tool for editing, sharing, and viewing photos - the iPhoto Help is saying:
    With iPhoto for iOS, you have everything you need to view, edit, and share your photos on your iPad, iPhone, or iPod touch (with iOS 7).
    You can organize your photos in iPhoto IOS in a limited way by tagging them, so that they will apear in albums: What are albums?
    To tag them with flags or keywords see: Flag, tag, hide photos
    Considering the limited space on IOS devices, the designers probably did not expect anybody to try to store so many photos on an iPad that it would be necessary to search for them other than using the predefined Views (Moments, Places) in the Photos.app, or iPhoto's albums. And any library organization you are doing in the Photos.app or iPhoto will not sync back to your computer.
    -- Léonie

  • HT204053 Can I search or locate different iPhone devices using one apple ID?

    Hello!
    Can I search or locate different iphone devices using one apple I.D.?
    Thanks!

    You can only use Find My iPhone for accounts that you can log into.  If you and your neighbor have different IDs and you only know your ID, than you can only track devices attached to your account.

  • Please let me know how can i pair up my IP5 with other IP5s ? whenever i switch on the bluetooth it still shows "Searching'' eventhough the other iphone 5 is kept near to my phone.

    Please let me know how can i pair up my IP5 with other IP5s ? whenever i switch on the bluetooth it still shows "Searching'' eventhough the other iphone 5 is kept near to my phone.

    Sineshraj wrote:
    Please let me know how can i pair up my IP5 with other IP5s ?...
    This is not supported.
    See here for Supported Bluetooth Profiles
    http://support.apple.com/kb/HT3647

  • How to display dynamic header title in the report?

    I have a req to display dynamic header title in the report.
    When a id is entered in the prompt text, it will display the user data based on that user_id.
    so similarly....the header title should vary each time when you select different user_id.
    How can we implement this?

    >
    Zack H wrote:
    > Lazaro,
    >
    > It depends on what you want displayed in the heading for each id.
    > Please elaborate.
    >
    > Thanks,
    > Zack H.
    Zack..I have several projects listed under several project id's...
    so when a user selects project id 00164 then it should display something like "Project document for Jon Doe"
    again when the user selects project id as 00192 then it should display something like "project document for Zimmerman"
    Did you get it??

  • How to display header title for 0MATERIAL texts in the query output?

    Dear Bwers,
    I have a requirement where i need to display headers titles for 0MATERIAL texts in the query output. (example "Material description"). Any ideas on how to do this?
    Thanks
    Raj

    Kamal,
    Its is as below:
    <b>Vendor</b>    <b>Vendor Name</b>
    1001 ---            Bright Industries
    1002 ---            Glow Industries
    I want to display the header title "Vendor Name" as the  title in the column instead of displaying the text without any header title.
    Thanks
    Raj
    Message was edited by:
            Raj Singh
    Message was edited by:
            Raj Singh

  • Is there any class to get the head, title, anchors of any page?

    hi, i am study at computer science and i have a senior project that is related to Focused Crawler.
    1 ) So, i have an issue. I have to get head,title,metas, anchors of any page. But, i don't want to recode it, may be there any classes that performs my willings. For example:
    URL a = new URL(....)
    string1 = a.getHeadComponent();
    string2 = a.getTitleComponent();
    string3 = a.getMetas();
    string4 = a.getAnchors();
    As i written above, is there any code to get these components without extra codding?
    2 ) Is it possible to modulate download speed while downloading a page by using URL class of java?
    Thanks for responses.

    fuatsungur wrote:
    hi, i am study at computer science and i have a senior project that is related to Focused Crawler.
    1 ) So, i have an issue. I have to get head,title,metas, anchors of any page. But, i don't want to recode it, may be there any classes that performs my willings. For example:
    URL a = new URL(....)
    string1 = a.getHeadComponent();
    string2 = a.getTitleComponent();
    string3 = a.getMetas();
    string4 = a.getAnchors();
    As i written above, is there any code to get these components without extra codding? No.
    You have to open a connection. Get the input stream. Read the input stream. Parse the content.
    There are HTML parsers out there.
    >
    2 ) Is it possible to modulate download speed while downloading a page by using URL class of java?
    By using URLConnection? No.
    If you use raw sockets then increase speed maybe. But "modulate" not really either way.

  • In my Ameritrade account the sub-header titles don't work when selected.

    In my Ameritrade account the sub-header titles don't work when selected. Is it maybe an add on or the beta version 14.01a of firefox or something else?
    I can't give the address as it is a confidential site, sorry. But for example when you pick trade and try to select buy or sell tab it does nothing. I tried downloading the lastest beta version 14.01a which I like to use but this didn't help? Thank you.

    Start Firefox in <u>[[Safe Mode]]</u> to check if one of the extensions or if hardware acceleration is causing the problem (switch to the DEFAULT theme: Firefox/Tools > Add-ons > Appearance/Themes).
    *Don't make any changes on the Safe mode start window.
    *https://support.mozilla.org/kb/Safe+Mode
    *https://support.mozilla.org/kb/Troubleshooting+extensions+and+themes

  • How to copy the photo with file name at window 7 and search specific one in iphone 4s?

    How to copy the photo with file name at window 7 and search specific one in iphone 4s?

    Clendenen02 wrote:
    2) It would be equally helpful if there was something that would take the name of the picture file and spotlight comment, copy and paste it to a movie file's comments with the same name but obviously has different extention. For an example
    In a Pictures folder
    Name: Dark Knight, The.jpeg       Comment: (2008) Genre: Action...             <- copy comment
    In a Movie Folder
    Name: Dark Knight, The.m4v       Comment:                                               <- paste 
    and do this for all 700 files
    This Bash script will do it.
    Edit "PicDir" and "MovDir" to the location of your Folders
    (Note: The comment is written to the m4v file using xattr, so the Spotlight comment field appears blank in Finder, but the comment metadata is still indexed by Spotlight (If you add a Spotlight comment from Finder, it is stored both as an extended attribute and in a .DS_Store file)
    #!/bin/bash
    PicDir=$HOME/Desktop/Pictures
    MovDir=$HOME/Desktop/Movies
    for f in $PicDir/*
    do
         if [ ! -d "$f" -a "${f##*.}" == "jpeg" ]; then
              comment=$(mdls -raw -name kMDItemFinderComment "$f")
              if [[ $comment != "(null)" ]]; then
                   picname=${f##*/}
                   movname=${picname%.*}.m4v
                   if [ -e "$MovDir"/$movname ]; then
                         xattr -w com.apple.metadata:kMDItemFinderComment "\"$comment\"" "$MovDir"/$movname
                   fi
              fi
         fi
    done

  • Header title in the BEx Analyzer

    Hi,
    Can anybody list the steps to create a header title(column header) using VBA. I am succesful in embedding the title, but it is not seen on refreshing.

    what do u mean "one time use" just save a workbook and publish that.
    I often find on these forums that people rely solely on queries and forget that workbooks were designed to do exactly what you want.  Including adding comments, formating, titles, adding additional excel calculations, creating drop sheets, etc.
    Just embed the query in a workbook and publish that workbook to users then all the formating will be saved.

  • When I search for "find my iPhone" on my mac, it doesn't find the app.

    So I have find my iphone installed on my iPhone & it finds my phone & my mac.
    Now I'd like to install in on my mac. It's more practical that if I lose my iPhone I'll use my Mac to find it.
    When I search for "find my iPhone" in the App store, it can't find any apps by that name.
    Closest is find my mouse.

    On your iPhone, go to Settings > Location Services > scroll down to Find My iPhone, tap and turn location services ON.

  • Setting Scroll Area Header Title Dynamically

    Hi guys
    I am having a problem, I want to set the Scroll Area Header Title in a sub-page Dynamically.
    is there any way to achieve that?
    Thanks for the answer

    It is not possible to set scroll area header dynamically using Peoplecode.
    May be you can have multiple scroll areas and display/hide each one accordingly.

  • Game Controller for Apple iPhone 5?

    is Apple Inc making a Game Controller for Apple iPhone 5 64GB ?? Cause i heard they were, that would be a very good idea? I Read about it on the internet.

    This product will be officially be available in mid November. It will be featured in the coming CES Show. I will keep you update on the progress.
    You may also send me email on the matter.

  • Searching Emails on the Iphone?

    Is there a way to search emails on the Iphone? Lets say I have over 400 emails on my phone, is there a way to search for an email from a specific sender or on a specific subject? This is a standard feature of windows mobile and RIM mobile devices and is needed here.

    Perhaps you should direct your input here: http://www.apple.com/feedback/
    Apple will not hear you here on this user-to-user support forum.
    There isn't currently any way to do this, but it might be made available in future updates.

Maybe you are looking for

  • I need the Click Once Add-in for 5.0.1 to run a software application on Win 7. Is this available?

    We run a software designed to work with Microsoft's ClickOnce technology. I used the add-on FFClickOnce 0.8 with the older version of Firefox but it is not compatible with 5.0.1. Now I am back to IE :(. Is there a new add-on like this to use with the

  • Error while executing WDA with PDf form

    Hi, when i'm executing WDA with PDF form i'm getting the following error message. i've checked for Reader credential properties from Basis, they say evething is okay. http://help.sap.com/saphelp_nw2004s/helpdata/en/56/f2c94a069f44a785b85748e11f82a0/c

  • Index Entries in 9i

    Hi, In older versions of designer 1.3.2 Index entries are available for foreign keys. We have migrated the repository from 1.3.2 to 9i and Index entries are not available in the design editor for foreign keys.When we generate a table in 9i we get err

  • Yet  another "There was an error writing metadata to..." post

    I know there have been several posts like this one on the forums, but I thought I'd start a new thread due to the fact that I tried a bunch of fixes that didn't work. Specifically, I get the above-mentioned error when trying to add keywords to DNG fi

  • DE logon not possible in NW 7.3

    A cusotmer is reporting that in their newly installed NW 7.3 system,DE language is not available in RSCPINST.So they can't logon with DE.Is this language deactivated defautly in NW 7.3 release? Thanks&Regards Jie Bai