What is Best Way to Input Decimal Numbers with iPhone SDK? - iphone

So after finally learning how to store user input into a variable, I am realizing it is rather difficult to have the user input numbers with decimals. The Number KeyPad doesn't allow a decimal part, and if I use Numbers & Punctuation it looks a bit weird.
So do I have to use a number Picker to smoothly allow users to input numbers? OR should I just use the Numbers & Punctuation since I was able to learn how to store that input (almost)?
Any help would be greatly appreciated.

You could always follow the same philosophy used for a Done button on the number keypad. Basically, you make your own decimal point button in that empty space in the lower-left.
Just follow the directions for adding and monitoring the button. The only thing you would need to change would be #selector(doneButton:) to #selector(decimalButton:). Your method for the decimal button would be:
- (void)decimalButton: (id) sender {
myTextField.text = [myTextField.text stringByAppendingString:#"."];
}

For my app I rolled my own number keypad. Created a modal view with all the buttons I needed, and when my UITextfield subclass becomes first responder I animate it in.
Quite a bit of work, but you can also customise the look & feel (with your own nice buttons etc) which is what I wanted for my app.
Update: My DecimalKeyboardViewController:
I actually use a subclass of UIControl instead of a UITextfield because I display it in some custom way. If I was to subclass UITextfield I'd do something like this:
#interface DecimalNumberTextfield : UITextfield {
NSDecimalNumber *value;
}
#property (nonatomic, retain) NSDecimalNumber *value
#end
#implementation DecimalNumberTextfield
- (BOOL)becomeFirstResponder
{
if ([super becomeFirstResponder]) {
[[DecimalKeyboardViewController sharedDecimalKeyboardViewController] showForField:self];
return YES;
} else {
return NO;
}
}
- (BOOL)resignFirstResponder
{
if ([super resignFirstResponder]) {
[[DecimalKeyboardViewController sharedDecimalKeyboardViewController] hide];
return YES;
} else {
return NO;
}
}
- (void)setValue:(NSDecimalNumber *)aValue {
// you need to set value and update the displayed text here
}
#end
Here is the DecimalKeyboardViewController. You'll need to create the nib file and add tags to the buttons (0-9 for the numbers probably, and other tags for the other buttons that you'd use), then hook up the buttons to -buttonPressed::
#interface DecimalKeyboardViewController : UIViewController {
DecimalNumberTextField *fieldBeingEdited;
}
#property (nonatomic, retain) DecimalNumberTextField *fieldBeingEdited;
+ (id)sharedDecimalKeyboardViewController;
- (void)showForField:(DecimalNumberTextField *)aTextField;
- (void)hide;
- (IBAction)buttonPressed:(id)sender;
#end
#implementation DecimalKeyboardViewController
static DecimalKeyboardViewController *sharedViewController;
+ (id)sharedDecimalKeyboardViewController
{
if (!sharedViewController) {
sharedViewController = [[DecimalKeyboardViewController alloc]
initWithNibName:#"DecimalKeyboardViewController"
bundle:[NSBundle mainBundle]];
}
return sharedViewController;
}
- (void)showForField:(DecimalNumberTextField *)aTextField
{
self.fieldBeingEdited = aTextField;
// add ourselves to the window unless we're there already
UIWindow *theWindow = self.fieldBeingEdited.window;
CGRect frame = self.view.frame;
if (!self.view.superview) { // add ourselves to the UIWindow unless we're already visible
frame.origin.y = theWindow.frame.size.height; // we start just out of sight at the bottom
self.view.frame = frame;
[theWindow addSubview:self.view];
}
// start animating
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
// animate the keyboard in
frame.origin.y = theWindow.frame.size.height - frame.size.height;
self.view.frame = frame;
// GO!
[UIView commitAnimations];
}
- (void)hide
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
if (self.view.superview) {
CGRect frame = self.view.frame;
frame.origin.y = self.view.superview.frame.size.height;
self.view.frame = frame;
}
[UIView commitAnimations];
self.fieldBeingEdited = nil;
}
- (IBAction)buttonPressed:(id)sender
{
UIButton *button = (UIButton *)sender;
NSDecimalNumber *oldNumber = self.fieldBeingEdited.value;
NSDecimalNumber *newNumber;
switch (button.tag) {
// calculate the new number based on what button the user pressed
}
// update the DecimalNumbertextfield
self.fieldBeingEdited.value = newNumber;
}
#end
Update 2: Since I subclassed UIControl I didn't have to deal with the standard keyboard popping up. If you subclass UITextfield I'd think the normal keyboard would be displayed as well. You'd have to prevent that somehow (not sure how) or subclass UIControl like I did.

If you don't want to go with Chris's answer, you could use numbers and punctuation keypad, and then "disable" all non digit/decimal point inputs by implementing the methods of UITextFieldDelegate

In the SDK 3.0 release notes, Apple wrote the following warning:
Don't draw custom buttons on top of existing keyboards. Any number of drawing, event, or compatibility problems could come up.
Now it's true, they have been accepting applications that add a button over an existing keyboard, however this technique uses an undocumented link to the UIKeyboard View and could easily be rejected the next time it's submitted. Technically it falls into the undocumented API realm, however I don't believe their automated tools pick it up so it's not being flagged.
You should post a bug on the Apple Developer Connection website, since they are counting the number of bug reports on this issue before they will address it formally...
There are an number of ways they could fix this, including:
1) Support more predefined keyboard options (decimal, currency, etc).
2) Expose the UIKeyboard methods
3) Provide customizing keyboard options that can be localized
If you intend to localize your App, you will have problems with different keypad sizes when you overlay a "." key on the empty space on one of the existing keypad (same problem that the "Done" button has in that approach).
I am currently using the overlayed "." in one of my own Apps, and will probably end up creating an entirely custom "decimal" keypad to replace this so I don't risk being rejected in an App update in the future.
-t

Related

Scroll on textField when begin Editing and keyboard appear

I've a viewController composed by an UIImageView that fills the whole view and two textField located at the center of the view. All this is located inside a ScrollView.
I use Storyboard and I disabled the autolayout.
When I click on a textField, and thus opens the keyboard, I'd like that the scroll is displaced directly on textField. How can I do that?
Consider that your TextField outlet is named txtField then implement UITextField Delegate using
txtField.delegate = self;
Considering that your ScrollView outlet is named scrollView. Implement the Textfield Delegate method:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(#"%#",NSStringFromCGRect(textField.frame));
[scrollView scrollRectToVisible:textField.frame animated:YES];
}
Hope this helps.
Do let me know if you need more help.
I usually use this successfully:
http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
Add your controller as an observer of the keyboard notifications. When you receive the notification, resize the scroll view frame and / or set the content offset (depending on the exact effect you want and content size you have).
Here are several options that I've used before:
Apple's Doco. See the section titled Moving Content That Is Located Under the Keyboard
Cocoa With Love article, Sliding UITextFields around to avoid the keyboard
If you have several text fields or other form elements in your view, you could alternatively use something like EZForm. It does automatic repositioning of views to keep input fields visible, and also handles input validation and other useful form-related stuff.
You can convert the text field coordinate system into Scroll view coordinate system. Use the below code
-(void)rearrangeView{
// previous
if (txtActiveField == txtUsername) {
CGPoint pt;
CGRect rc = [txtUsername bounds];
rc = [txtUsername convertRect:rc toView:scrollViewLogin];
pt = rc.origin;
pt.x = 0;
pt.y -= 40;
[scrollViewLogin setContentOffset:pt animated:YES];
}
else if (txtActiveField == txtPassword) {
// [self.txtEmail becomeFirstResponder];
CGPoint pt;
CGRect rc = [txtPassword bounds];
rc = [txtPassword convertRect:rc toView:scrollViewLogin];
pt = rc.origin;
pt.x = 0;
pt.y -= 40;
[scrollViewLogin setContentOffset:pt animated:YES];
}
}
#pragma mark- UITextField Delegate
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
txtActiveField = textField;
//txtActiveField.placeholder = #"";
[self rearrangeView];
return YES;
}
Here txtActiveField is instance variable of type UItextField

How to create simple menu?

I'm trying to create simple (facebook like) menu in my app. I've found several questions, most of them had accepted answer, but usually answer is to use some programs done by developers.
These programs are often in old version of xCode (one, that didn't use storyboards) and those, that were done in storyboard, were too complicated for me to implement in my app.
So I found one question, which had as an answer something like this:
1. Create your menu view controller (UITableViewController for me)
2. Hide this controller in your initial view controller :
MenuViewController *menView = [self.storyboard instantiateViewControllerWithIdentifier:#"Menu"];
[self.view sendSubviewToBack:menView.view];
3 Create a button (maybe pan gesture later), in it's method, do something like this:
-(IBAction)menuButtonPressed:(id)sender
{
CGRect destination = self.navigationController.view.frame;
if (destination.origin.x > 0) {
destination.origin.x = 0;
} else {
destination.origin.x +=254.5;
}
[UIView animateWithDuration:0.25 animations:^{
self.navigationController.view.frame = destination;
} completion:^(BOOL finished)
{
self.view.userInteractionEnabled = !(destination.origin.x > 0);
}];
}
What this does I guess, it's that it basically moves your view to the right by fixed length. I suppose, that your view, that you sendedToBack (your UITableView) should be exposed and interactable. However, all it does for me, is moving top view to the right, and leaving blank black-colored screen behind.
Now I think, that my problem is either bad instantiation of menuView, or just that I understanded this guide wrong.
If anyone knows, how to deal with this, I would be very thankful for an answer. Maybe there is some already done app, that is as easy as this to understand and hopefully easier to implement in my code :)
Thanks!
I would do this using container views in storyboard. You can size the left one how you like, then add a right one next to it, and in the inspector change its width to 320 -- most of it will go off the screen to the right, and it will resize its embedded controller to be full screen size. You can delete the view controller that you get with the left container view, then drag out a table view controller, and connect it from the left view with an embed segue (it will be the only choice when you control drag from the container view). I added two swipe gesture recognizers (one left and one right) to the main controller's view and connected them to the 2 methods in the main controller. Then in the main controller I have this code in the .h:
#interface ViewController : UIViewController
#property (weak,nonatomic) IBOutlet UIView *rightView;
#property (assign,nonatomic) CGRect rightRect;
#end
And in the .m, only this:
#implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.rightRect = self.rightView.frame;
}
-(IBAction)revealSidebar:(id)sender {
[UIView animateWithDuration:.3 animations:^{
self.rightView.frame = self.view.window.frame;
}];
}
-(IBAction)hideSidebar:(id)sender {
[UIView animateWithDuration:.3 animations:^{
self.rightView.frame = self.rightRect;
}];
}
#end

UIPicker specific question(iphone)

I am starting to learn to use the UIPicker in an application. what I want to do is that when the user clicks on the zipcode textbox, I want the uipicker to pop up and display list of zipcodes available. Just like a drop down in c# or VB.net. Do I have to create a new view and place the uipicker there?
Thanks
You need a view for placing a text box. It does not matter if it needs to be a new view or the old view - just place the text box in the view you require.
make sure that
textField.inputView = yourPickerView;
In order to have a UIPickerView appearing in your app you do not need an additional view.
Assuming you are in a UIViewController:
#interface MyController : UIViewController {
UIPickerView* mPicker;
}
-(void)showPicker;
-(void)hidePicker;
#end
-(void)showPicker {
[self.view addSubview:mPicker];
mPicker.center = CGPoint // set out of sight
[UIView beginAnimations:nil context:nil];
// do your transformations
[UIView commitAnimations];
}
-(void)hidePicker {
// do your exit animations
}
You can also add a delegate function to the second animations to remove the mPicker from the superview.
For more information have a look at the UIView Reference.

How can I make the keyboard disappear?

Is there a way to make a keyboard disappear without resignFirstResponder? I have a UITextField, and I'd like it to be able to accept new text and still have the insertion point (flashing cursor) visible without the keyboard being on screen.
When I perform a [textField resignFirstResponder] I can still insert text, by appending to the textField.text, but I can't see the insertion point anymore.
Is there a standard way to make the keyboard animate out, while having my textField remain first responder?
Thanks.
Found an answer to this question. It's not standard though, and like Dave says, may be taboo for the app reviewers. Using the code from this page as a starting point:
http://unsolicitedfeedback.com/2009/02/06/how-to-customize-uikeyboard-by-adding-subviews/
I added in an animation block. You can dismiss the keyboards view with a standard looking animation, but whatever is first responder will retain that status. Really, the keyboard is just hidden off screen.
- (void)hideKeyboard
{
for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
// Now iterating over each subview of the available windows
for (UIView *keyboard in [keyboardWindow subviews]) {
// Check to see if the view we have referenced is UIKeyboard.
// If so then we found the keyboard view that we were looking for.
if([[keyboard description] hasPrefix:#"<UIKeyboard"] == YES) {
// animate the keyboard moving
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.4];
// remove the keyboard
CGRect frame = keyboard.frame;
// if (keyboard.frame.origin.x >= 0) {
if (keyboard.frame.origin.y < 480) {
// slide the keyboard onscreen
//frame.origin.x = (keyboard.frame.origin.x - 320);
// slide the keyboard onscreen
frame.origin.y = (keyboard.frame.origin.y + 264);
keyboard.frame = frame;
}
else {
// slide the keyboard off to the side
//frame.origin.x = (keyboard.frame.origin.x + 320);
// slide the keyboard off
frame.origin.y = (keyboard.frame.origin.y - 264);
keyboard.frame = frame;
}
[UIView commitAnimations];
}
}
}
}
I wrote in code to dismiss the keyboard to the left and to the bottom of the screen. I don't know what will happen when you eventually resignFirstResponder, but it might be an idea to reset the keyboard frame when you do that.
If there is, then it's not documented in the iPhone API. Also, what you're asking for does not make sense. You want to have the insertion point in a UITextField. OK, great. But you also want the keyboard to go away? Then what's the point of the textfield having the focus? How are you going to input data into the textfield? If you want to have a custom keyboard, then just display it on top of the keyboard. I can't think of a good reason why you'd want the cursor to be visible but not have some sort of data entry mechanism. That would break UI convention and might even get your app rejected.

Changing the size of the UISearchBar TextField?

I have a UITableView with an Index on the side; I want to add a UISearchBar to it, but the index overlaps with the "x" to clear the search. I've noticed in the Contacts application, the textfield within the UISearchBar is resized to accommodate this, but I can't work out how to do this in my own app.
I have tried the following in my viewDidLoad, but it does not seem to work.
UITextField * textField = (UITextField *)[[self.search subviews] objectAtIndex:0];
CGRect r = textField.frame;
[textField setFrame:CGRectMake(r.origin.x, r.origin.y, r.size.height, r.size.width-30)];
Any ideas?
it's much easier than all these suggestions. In interface builder, instead of putting the Search Bar as the header of your Table View, you can put a View instead. Then, put a Navigation Bar inside this View. Grab the left resizing handle of the Navigation Bar and pull it to the right until the N B is only 25 pixels wide. Clear out the Title in the N B (double click to select it, then delete). Then, add a Search Bar into the same View. Move its right resizing handle to the left, adjust so that it abuts the N B. That's it.
You can enable a cancel button if you want too and it also won't overlap the index (remains within the search bar).
Apparently a Table View can only have 1 subview in its header, that's why you need to put the View first, then the N B and Search Bar inside it.
UPDATE: see Beginning iPhone Development from Apress, p. 241 of SDK 3 edition. You just disable the index while searching.
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (isSearching) {
return nil;
}
return keys;
}
Also they talk about adding a magnifying glass to the top of the index.
Great book all around.
Why not just make the actual UISearchBar smaller horizontally, and place an (empty) UINavigationBar to the right of it? They will render the exact same background.
Better than hacking the internals of Apple's objects that could change.
Also, when animating the UISearchBar's width, you'll notice that the inner text field is not animated along with it. You can fix this by calling UISearchBar's "layoutSubviews" within your animation block after changing its frame. (that's where it determines the size of the inner text field)
Ok, I've come up with a solution.
Create a subclass of UISearchBar
Include this code in the drawRect: method.
UITextView * textField = [self.subviews objectAtIndex:0];
textField.frame = CGRectMake(5, 6, (310 - kRightSideMargin), 31);
[super drawRect:rect];
Note: kRightSideMargin is a constant I set in my header file; I have it set to 25.
Thanks for the suggestions from everyone else.
As Padraig pointed out all you have to do is subclass out the searchBar. Create your UISearchBar subclass, and add the following code into the layoutSubviews method:
- (void)layoutSubviews
{
UITextField *searchField;
for(int i = 0; i < [self.subviews count]; i++)
{
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
searchField = [self.subviews objectAtIndex:i];
}
}
if(!(searchField == nil))
{
searchField.frame = CGRectMake(4, 5, 285, 30);
}
}
This loops through all the subviews and checks them against type UITextField. That way if it ever moves in its line up of subviews this will still grab it. I found 285 to just wide enough not to overlap with the index of my tableView.
As of iOS 6, the navigation bar solution didn't work well for me because of slightly different looks now between the UISearchBar and UINavigationBar. So, I switched to something similar to Padraig's approach by subclassing the UISearchBar.
#interface SearchBarWithPad : UISearchBar
#end
#implementation SearchBarWithPad
- (void) layoutSubviews {
[super layoutSubviews];
NSInteger pad = 50;
for (UIView *view in self.subviews) {
if ([view isKindOfClass: [UITextField class]])
view.frame = CGRectMake (view.frame.origin.x, view.frame.origin.y, view.frame.size.width - pad, view.frame.size.height);
}
}
#end
Edit: Ah, I haven't tried it, but I think you might be able to set a navigation bar's clipToBounds = YES to turn off it's new shadow, thereby creating a consistent look again between the two controls.
I am using ViewDeck and want to show a UISearchbar inside the leftController.
Now the problem is if I open the left side which contains the navigation, the right bit overlaps my search field.
I got rid of this by over writing UISearchBar, the textfield will always have the same width, but in one case there is the ViewDeck overlapping and in the other case I hide the ViewDeck-bit and then the cancel button will take up the space:
Subclassing UISearchBar
#import "ViewDeckSearchBar.h"
#define kViewDeckPadding 55
#interface ViewDeckSearchBar()
#property (readonly) UITextField *textField;
#end
#implementation ViewDeckSearchBar
static CGRect initialTextFieldFrame;
- (void) layoutSubviews {
[super layoutSubviews];
// Store the initial frame for the the text field
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
initialTextFieldFrame = self.textField.frame;
});
[self updateTextFieldFrame];
}
-(void)updateTextFieldFrame{
int width = initialTextFieldFrame.size.width - (kViewDeckPadding + 6);
CGRect newFrame = CGRectMake (self.textField.frame.origin.x,
self.textField.frame.origin.y,
width,
self.textField.frame.size.height);
self.textField.frame = newFrame;
}
-(UITextField *)textField{
for (UIView *view in self.subviews) {
if ([view isKindOfClass: [UITextField class]]){
return (UITextField *)view;
}
}
return nil;
}
#end
ViewController class
In my Navigation class I need to overwrite these two UISearchbarDelegate methods in order to go to fullscreen with the search results:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
[self.viewDeckController setLeftSize:0];
// I am also using scopes, which works fine (they fade out when not searching)
self.searchBar.scopeButtonTitles = #[#"Food",
#"Beverages",
#"Misc"];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
self.viewDeckController.leftSize = 55;
}
Result
ViewDeck showing to the right:
(source: minus.com)
Search in Fullscreen (The button and the scope buttons are animated in).
(source: minus.com)
searchBar.layoutMargins = UIEdgeInsetsMake(0, 0, 0, rightPad);
My old solution of changing the UITextField frame stopped working in iOS 13. Putting a UINavigationBar to the right of the UISearchBar never worked well for me as they had different looks at top and bottom.
Sorry to drag this all up again.
I wanted the UISearchBar to be shorter, and I'm using a UISearchBarController, but without actually wanting the index. This is because I have an overlay to the right:
To do this, I fake a sectionIndex with one blank item, then hide it. Here's how I do that:
- (void)hideTableIndex {
for (UIView *view in [tableView subviews]) {
if ([view isKindOfClass:NSClassFromString(#"UITableViewIndex")]) {
view.hidden = YES;
}
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)aTableView {
if (aTableView == self.searchDisplayController.searchResultsTableView) {
return nil;
} else {
[self performSelector:#selector(hideTableIndex) withObject:nil afterDelay:0];
return [NSArray arrayWithObjects:#"", nil];
}
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return 0;
}
This shortens the the UISearchBar and hides the index so it can't be tapped (a small section would otherwise hand to the left of the overlay that when tapped would scroll the UITableView to the top). Like this:
Best of all, when you use the search, you still get the full width bar:
Just put a UIView and put the search bar inside that UIView. UIView must be of same size as UISearchBar.
this worked for me.
The text field used in UISearchBar is a subclass of UITextField called UISearchBarTextField.
AFAIK, there's no way to resize a UISearchBarTextField using the public API, and the private API doesn't reveal much either.
Maybe you can take a look at UISearchBarTextField's subviews, if it has any.
UPDATE: It doesn't.
UPDATE 2: I think you should take a look at UITextField's rightView property. The below code, although it doesn't work, seems like a good starting point:
UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[textField setRightView:emptyView];
[textField setRightViewMode:UITextFieldViewModeAlways];
[emptyView release];
Sorry for Necroposting, but I found another way to make a little space on the right of the textfield.
I was having the problem, that I had an indexed tableview with a searchbar as the first row. Now the index and the searchbar (made in IB, btw.) were overlapping. It tried almost everything with no success. It seems that the width and height properties of the textifield don't respond... So I came up with this:
searchBar.showsCancelButton = YES;
UIView *cButton = [searchBar.subviews objectAtIndex:2];
cButton.hidden = YES;
I still can't adjust the size of the space, but this does it for now... although... pretty weird solution...
Everyone has provided ways to modify the UI. I have discovered how to obtain identical results. You must provide the following two implementations:
Use UISearchDisplayController
More importantly, make sure you initialize it with:
- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController
Failure to set a valid UISearchBar (or passing nil) will prevent the adjustment of the UITextField for the index.
You must return a valid array of titles by implementing:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
If you return nil, the index will not be displayed, and the UITextField will not be properly adjusted.
I've submitted a bug report to Apple, suggesting that it seems logical that only #2 should be required, not #1. I have found nothing in the Human Interface Guideline (iPhone HIG) requiring use of the UISearchDisplayController.
The key is to use the "Search Bar and Search Display Controller" and not the "Search Bar" when using Interface Builder.
It kind of looks as though Apple resize the view (note that the index is animated to the right, off screen), making it bigger than the screen.
I would imagine that you'd need to implement the searchBarTextDidBeginEditing: method of the UISearchBarDelegate to trigger this at the appropriate point. This does, however, feel a bit hacky do maybe there's a better way of doing it.
Another appraoch (though tedious) would be to resize the search bar and fill the 'gap' with a navigation bar. Works for me.
What I've come up with isn't too much better. Basically, I make an empty view with the frame that I want to use for the search bar. Then I create a UIToolbar to go behind the search bar. Be sure to set its frame to the same frame as the UIView, except that the Y value has to be -1; otherwise, you'll get two borders drawn at the top. Next create your UISearchBar, but set the frame's width to 30 (or whatever makes sense for your app) less than the UIView. Add them as subviews and set your UIView as the tableHeaderView.
I followed Mike's advice by making a UIView, then putting a Navigation Bar and UISearch Bar inside it. Only problem is first time the search bar is shown its background is the same as a Navigation Bar normally?
Interestingly, if I activate the search, then click cancel the background of this 'fixed'!?
I'm using SDK 3.0, so I removed the UISearchBar item made when I dragged a UISearchDisplayController in to my NIB, then made the view as described above and wired it up to the file owner and the searchBar outlet in the search display controller.
It work fine!!!
[searchBar setContentInset:UIEdgeInsetsMake(5, 0, 5, 35)];