UISearchBar keyboard appearance - iphone

According to this question, we can change keyboard appearance of any UITextField in iOS Can the alert keyboard be used for any text field on iOS?
But what about the UISearchBar? Is there a way for that, because [searchBarInstance setKeyboardAppearance:UIKeyboardAppearanceAlert]; doesn't work, since UISearchBar lacks of this method.

you can do like this,
for(UIView *subView in searchBar.subviews)
if([subView isKindOfClass: [UITextField class]])
[(UITextField *)subView setKeyboardAppearance: UIKeyboardAppearanceAlert];
see iPhone UISearchBar & keyboardAppearance

Related

Change UIPicker appearance

So I'm facing this problem, the standard UIPicker doesn't look good in my (proto) app and I would really change its appearance.
I've already googled it and found this useful link http://aralbalkan.com/2985. Looks good but I'm wondering if there isn't an easier way to do it.
Here on stack overflow I've found this thread Is it possible to 're-skin' the IOS Date Picker?, it's "unsolved" but pointing to the first article.
I also did a tutorial in Apress Book "Beginning Iphone development" (chapter 7 I think), very useful, but there I was changing just the content of the columns, not the full appearance of it.
Just to be clear, it would be great to have something like this:
Anyone has a good tutorial/link/suggestion for an Objective-c rookie?
Thx in advice
EDIT:
So I've implemented the method detailed in the two answers below and it works like a charm. But I'm still stuck with the background color ....
the numbers shoud be able to create via using UIPickerViewDelegate's pickerView:viewForRow:forComponent:reusingView:, while the comma could be added via addSubView:.
or you go down another road and use a open source alternative, i.e. AFPickerView
You can manipulate teh views in the hierarchy — but probably it is easier to recreate the picker …
-(void)viewDidAppear:(BOOL)animated
{
for (UIView *view in [self.pickerView subviews]) {
NSLog(#"%#", view);
}
[(UIView *)[[self.pickerView subviews] objectAtIndex:1] setBackgroundColor:[UIColor blueColor]];
[(UIView *)[[self.pickerView subviews] objectAtIndex:0] setHidden:YES];
[(UIView *)[[self.pickerView subviews] lastObject] setHidden:YES];
for (UIView *view in [(UIView *)[[self.pickerView subviews] objectAtIndex:2] subviews]) {
NSLog(#"> %#", view);
}
[[[(UIView *)[[self.pickerView subviews] objectAtIndex:2] subviews] lastObject] setHidden:YES];
}
use the delegate of the UIPickerView. Create a method called
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
So at this point, you can create a UIView (or subclass). At this point, you have full control over what the view will display. You can change the background color and alpha. And if you subclass UIView, you can have your own drawing routines.

How to cancel the keyboard in UISearchbar?

I'm using UISearchBar in my application and it serves as both an edit field as well as a search. So when I want to disappear the keyboard I have to use cancel button in UISearchBar but I can't have that cancel button on screen, so how could T make keyboard disappear when not used without using cancel button. Please help me as i'm new to iPhone application development.
Thanks in advance!
Use this:
[UISearchBar resignFirstResponder];
Just replace the word UISearchBar with the name of the object you have created.
Are you looking for ways you can dismiss the keyboard or how to actually do that programmatically? If programmatically, then [UISearchBar resignFirstResponder]. If you are looking for a possible way for the user to achieve that you can either make the return button on the keyboard resign its first responder status when pressed, or attach a UIGestureRecognizer to your view and set it up so that when the user clicks outside the keyboard, this keyboard goes away.
simply all you need to do is to get UITextfield control from the UISearchbar and then set UITextfield's delegate to whatever delegate that will perform -(void) textFieldShouldReturn:(UITextField *)textField
-(void)viewDidLoad{
UIView * subView;
NSArray * subViews = [searchbar subviews];
for(subView in subViews)
{
if( [subView isKindOfClass:[UITextField class]] )
{
((UITextField*)subView).delegate=self;
((UITextField*)subView).returnKeyType=UIReturnKeyDone;
break;
}
}
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return TRUE;
}

How to set Custom keyboard specific to only a UItextfield

How to set Custom keyboard specific to only a UITextField? When I am changing using this method, all the keyboards in my application are changed to this new custom keyboard. I added:
[[NSNotificationCenter defaultCenter] addObserver:self.view
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
in a UIViewController. But after going to that UIView, keyboards in other UIViewControllers also look like new custom keyboard. How can i limit the custom keyboard to only one UIView? Please help me. Thanks in advance.
UITextField* textField;
UIView* customKeyboard;
textField.inputView = customKeyboard;
Similar thread: iPad custom Keyboard GUI
If you subclassed UITextView (as that tutorial shows), then all instances of that subclass will use the toolbar with a dismiss button.
If you don't want the toolbar, then don't use the subclass, just use the original UITextView.
You can try checking for the textfield that you want on the textFieldShouldBeginEditing like so:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == YOUR_DESIRED_TEXTFIELD) {
[self openCustomKeyboard];
}
return YES;
}
My problem was once am loading custom keyboard, it remains everywhere in other UIviews of application. So i checked existence of UIToolbar in other UIkeyboard subviews and removed . Now its working fine..
for(UIView* keyboardToolbar in [keyboard subviews]){
if([[keyboardToolbar description] hasPrefix:#"<UIToolbar"] == YES)
{
[keyboardToolbar removeFromSuperview];
}
}

Remove clear button (grey x) to the right of UISearchBar when cancel button tapped

Right, to begin my question, here's some screenies of the problem already solved by the Spotify app:
Spotify's Step 1: Standard UISearchBar not in editing mode.
Spotify's Step 2: UISearchBar now in editing mode. Search term entered. Cancel button slides in from the right, and the clear button (grey x) appears.
Spotify's Step 3: Cancel button pressed; keyboard slides out and the search bar is no longer in editing mode. Search term remains and the grey x button is now hidden.
At present, the following code fires off when my cancel button is pressed:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
[searchBar setShowsCancelButton:NO animated:YES];
}
Which results in:
My Step 3: Search bar now not in editing mode. Cancel button and keyboard has slid out. Search term remains but so does the grey x.
So, my question is this: given that -resignFirstResponder (and -endEditing:, FYI) does not hide the grey x button when a search bar has had text entered into it, how does one hide it?
Thanks again, friends.
The problem is that UISearchBar doesn't expose it's text field, and manages the properties on the text field itself. Sometimes, the values of the properties aren't what you want.
For instance, in my own app, I wanted the keyboard style for my search bar to use the transparent alert style.
My solution was to walk through the subviews of the search bar until you find the text field. You should then be able to set the clearButtonMode property, using something like UITextFieldViewModeWhileEditing as a parameter.
This should make it so that the clear button is only shown while the text field is editing.
You want to do this on viewDidLoad or something early, so it's set before you start using it (but after the search bar is initialised.
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:#protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeWhileEditing];
}
}
Looks like iOS 7 changed the view hierarchy of UISearchBar, and the text box is deeper in the view (The above solution didn't work for me). However, modifying the above solution to traverse the whole hierarchy works:
[self configureSearchBarView:[self searchBar]];
- (void)configureSearchBarView:(UIView*)view {
for (UIView *subview in [view subviews]){
[self configureSearchBarView:subview];
}
if ([view conformsToProtocol:#protocol(UITextInputTraits)]) {
[(UITextField *)view setClearButtonMode:UITextFieldViewModeWhileEditing];
}
}
I'm building upon the previous answers because I started seeing crashes on iOS 7.1 unless I made the following change. I added an additional call to respondsToSelector for each view to make sure that setClearButtonMode: can be called. I observed an instance of UISearchBar getting passed in, which seems to conform to the UITextInputTraits protocol yet does not have the setClearButtonMode: selector, so a crash occurred. An instance of UISearchBarTextField also gets passed in and is the actual object for which to call setClearButtonMode:.
- (void)removeClearButtonFromView:(UIView *)view
{
if (!view)
{
return;
}
for (UIView *subview in view.subviews)
{
[self removeClearButtonFromView:subview];
}
if ([view conformsToProtocol:#protocol(UITextInputTraits)])
{
UITextField *textView = (UITextField *)view;
if ([textView respondsToSelector:#selector(setClearButtonMode:)])
{
[textView setClearButtonMode:UITextFieldViewModeNever];
}
}
}
You need to get the textField of the Search Bar
UITextField *textField = [searchBar valueForKey:#"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
use in - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar method.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
UITextField *textField = [searchBar valueForKey:#"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
}
A better way to do this in iOS7 is:
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setClearButtonMode:UITextFieldViewModeWhileEditing];
To expand on Jadariens answer if you never want the grey x to appear you need to use the following
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:#protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever];
}
}
Accepted answer does not work on iOS7+, here is the modified version as a Swift extension
extension UIView {
class func removeClearButton(svs: [UIView]) {
for sv in svs {
if let tv = sv as? UITextField where sv.conformsToProtocol(UITextInputTraits) {
tv.clearButtonMode = .Never
return
} else {
UIView.removeClearButton(sv.subviews)
}
}
}
}
Usage
UIView.removeClearButton(searchBar.subviews)
Hers is a category I wrote that does this
Category
#implementation UISearchBar (Additions)
- (void)setClearButtonMode:(UITextFieldViewMode)viewMode {
UITextField *textField = [self findTextFieldInView:self];
[textField setClearButtonMode:viewMode];
}
- (UITextField *)findTextFieldInView:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UITextField class]] ||
[subview.class isSubclassOfClass:[UITextField class]]) {
return (UITextField *)subview;
}
UITextField *textField = [self findTextFieldInView:subview];
if (textField) {
return textField;
}
}
return nil;
}
#end
Usage
[searchBar setClearButtonMode:UITextFieldViewModeWhileEditing];
There's a better way than any of the answers here, and you don't have to use private APIs or traverse subviews to do it.
UISearchBar has a built-in API for doing this:
[UISearchBar setImage:forSearchBarIcon:state]
The SearchBar icon key you want is UISearchBarIconClear, and you want the UIControlStateNormal state. Then give it a clear image for the image, and you're done.
So, it should look like this:
[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
For the (x) icon in searchBar. You can use below delegate method.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = YES;
}
for (UIView *subview in _search_bar.subviews)
{
NSLog(#"%#",subview.subviews);
for (UIView *subview11 in subview.subviews)
{
if ([subview11 conformsToProtocol:#protocol(UITextInputTraits)])
{
[(UITextField *)subview11 setClearButtonMode:UITextFieldViewModeNever];
}
}
}

iPhone UISearchBar & keyboardAppearance

When the keyboard appears, I want to set the
keyboardAppearance = UIKeyboardAppearanceAlert
I've checked the documentation and it looks like you can only change the keyboardType.
Can this be done without violating any of Apple's private API's ?
The best way that I found to do this, if you want to do it throughout your app, is to use Appearance on UITextField. Put this in your AppDelegate on launch.
[[UITextField appearance] setKeyboardAppearance:UIKeyboardAppearanceDark];
This should do it:
for(UIView *subView in searchBar.subviews)
if([subView isKindOfClass: [UITextField class]])
[(UITextField *)subView setKeyboardAppearance: UIKeyboardAppearanceAlert];
didn't find any other way of doing...
This no longer works on iOS 7 because the UISearchBar view hierarchy has changed. The UITextView is now a subview of the first subview (e.g. its in the searchBar.subviews[0].subviews array).
A more future proof way to do this would be to check recursively the entire view hierarchy, and to check for UITextInputTraits protocol rather than UITextField, since that is what actually declares the method. A clean way of doing this is to use categories. First make a category on UISearchBar that adds this method:
- (void) setKeyboardAppearence: (UIKeyboardAppearance) appearence {
[(id<UITextInputTraits>) [self firstSubviewConformingToProtocol: #protocol(UITextInputTraits)] setKeyboardAppearance: appearence];
}
Then add a category on UIView that adds this method:
- (UIView *) firstSubviewConformingToProtocol: (Protocol *) pro {
for (UIView *sub in self.subviews)
if ([sub conformsToProtocol: pro])
return sub;
for (UIView *sub in self.subviews) {
UIView *ret = [sub firstSubviewConformingToProtocol: pro];
if (ret)
return ret;
}
return nil;
}
You can now set the keyboard appearance on the search bar in the same way you would a textfield:
[searchBar setKeyboardAppearence: UIKeyboardAppearanceDark];
keyboardAppearance is a property of the UITextInputTraitsProtocol, which means that the property is set via the TextField object. I'm not aware of what an Alert Keyboard is, from the SDK it's a keyboard suitable for an alert.
here's how you access the property:
UITextField *myTextField = [[UITextField alloc] init];
myTextField.keyboardAppearance = UIKeyboardAppearanceAlert;
Now when the user taps the text field and the keyboard shows up, it should be what you want.