Friday, April 29, 2011

Xcode4/CoraData: Using LIKE to search SQLite Table - "String starts with"

Problem


I recently had a task where a UITableView should suggest autocomplete for a word I started to type into a UISearchBar/Search Display Controller.

From the top of my head I came up with the SQL query that I wanted to use:

SELECT string FROM table WHERE string LIKE 'S%';

This query should return all the strings that start with capital S.

Solution


For a NSPredicate the query has to look like this:

NSString *query = [NSString stringWithFormat:@"String LIKE '%@%%'", startOfString];

Most important here is that the percent sign needs to be escaped with another percent sign (%%).

Friday, April 15, 2011

Xcode4: Set Company/Organization Name for specific Projects

Another thing that changed in Xcode 4 is how to tell Xcode to use a certain Organization name instead of the default "__MyCompanyName__" or the company name that is tight to your Mac user account.

Most prominent this value shows up in the comment copyright header when you create a new file in Xcode4.

1. Click on your project root in the Project Navigator on the left.


2. Enable your Utilities view on the right while the project root is marked.


3. Select the File Inspector. To make sure you are in the right location, the Identity should display your Project Name.


4. Under Project Document is a text field called Organization. Enter here the Organization name you want to show up for all your new files that get generated in this project.


That's it. Let me know if you have any problems or comments.

Sunday, April 10, 2011

Objective C: Adding an Enter/Search Button to Number Pad on iPhone Apps

In my Xcode projects where I needed a button on the Number Pad to initiate the intended action I used this tutorial: UIKeyboardTypeNumberPad and missing return key.

I also implemented the updates described in the Internet that make the hack compatible with either iOS version, below 3.2 and above, including iOS 4, iOS 4.1, iOS 4.2 and iOS 4.3.

Another improvement compared to the tutorial is that I put the image in the Background of the Button and use a Label in the foreground to be able to use any Label I want and make it localizable.




Below are the steps from the above website with my additions to accomplish the above features:

Create and Add the button images to your project


The button will be placed on the number pad in your iPhone or iPad App. To make it look good the button should look like the other number pad buttons when it gets clicked and when not. That means that the button has to states.

I modified a button from number pad to look like the other buttons. You can use them in your project if you want.



Call them buttonUp.png and buttonDown.png or whatever you want and copy them in your xcode project.

Prepare your ViewController Header (.h)


Make sure you have set your keyboard as the delegate for the UILabel that uses the Keyboard.

in ExampleViewController.h:
@interface ExampleViewController : UIViewController {
 UITextField *textField;
}
...
@property (nonatomic, retain) IBOutlet UITextField *textField;
...
- (void)addButtonToKeyboard;
- (void)keyboardWillShow:(NSNotification *)note;
- (void)keyboardDidShow:(NSNotification *)note;
- (void)buttonClicked:(id)sender;
@end

Prepare your ViewController (.m)


- (void)viewDidLoad {
    [super viewDidLoad];
...
// add observer for the respective notifications (depending on the os version)
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];     
    } else {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    }
...
}

- (void) viewWillDisappear:(BOOL)animated{
 [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)addButtonToKeyboard {  
    // create custom button
    UIButton *yourButton = [UIButton buttonWithType:UIButtonTypeCustom];
    yourButton.frame = CGRectMake(0, 163, 105, 53);
    yourButton.adjustsImageWhenHighlighted = NO;
    //set font button size and type
    yourButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
    
    //set the label text of the button when its not pushed 
    [yourButton setTitle:@"SEARCH" forState:UIControlStateNormal];
    //set the color of the label text of the button when its not pushed
    [yourButton setTitleColor:[UIColor colorWithRed:0.302f green:0.33f blue:0.384f alpha:1.0f] forState:UIControlStateNormal];
    //set the background image of the button when its not pushed
    [yourButton setBackgroundImage:[UIImage imageNamed:@"buttonUp.png"] forState:UIControlStateNormal];

    //set the label text of the button when its pushed
    [yourButton setTitle:@"SEARCH" forState:UIControlStateHighlighted];
    //set the color of the label text of the button when its pushed
    [yourButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
    //set the background image of the button when its pushed
    [yourButton setBackgroundImage:[UIImage imageNamed:@"buttonDown.png"] forState:UIControlStateHighlighted];
    
    [yourButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
 
    // locate keyboard view
    UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView* keyboard;
    for(int i=0; i<[tempWindow.subviews count]; i++) {
        keyboard = [tempWindow.subviews objectAtIndex:i];
        // keyboard found, add the button
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
            if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
                [keyboard addSubview:yourButton];
        } else {
            if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
                [keyboard addSubview:yourButton];
        }
    }
}

- (void)keyboardWillShow:(NSNotification *)note {
    // if clause is just an additional precaution, you could also dismiss it
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 3.2) {
        [self addButtonToKeyboard];
    }
}

- (void)keyboardDidShow:(NSNotification *)note {
    // if clause is just an additional precaution, you could also dismiss it
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) {
        [self addButtonToKeyboard];
    }
}

- (void)buttonClicked:(id)sender{
        //lets the number pad disappear after your clicked your custom button
 [self.textField resignFirstResponder];
 ...
        //do here what you want after the button was clicked
}


Troubleshooting

So far I came across only one problem and that was that my picture where not added properly to my project. Therefore clicking worked, but the buttons didn't show up. You can test this by adding a UIImage view manually to your NIB and see if the image shows in the list of images that you could set.

Let me know if you have more issues or suggestions.