Using a UIButton inside a UITextField as a clear button - ios

what i am trying to do is do a custom clear button in a UITextField, currently i have got everything working except for the last part. Which is getting it to preform the clear action. However, i have not been able to work out how i can get it to clear, just the textField it is in.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[textField setTextColor:[UIColor colorWithRed:0.56f green:0.56f blue:0.56f alpha:1.00f]];
[textField setFont:[UIFont systemFontOfSize:14]];
textField.background = [UIImage imageNamed:#"whiteCell"];
UIButton *btnColor = [UIButton buttonWithType:UIButtonTypeCustom];
[btnColor addTarget:self action:#selector(clearText:) forControlEvents:UIControlEventTouchUpInside];
btnColor.frame = CGRectMake(0, 0, 25, 25);
[btnColor setBackgroundImage:[UIImage imageNamed:#"clearBut"] forState:UIControlStateNormal];
textField.rightView = btnColor;
textField.rightViewMode = UITextFieldViewModeAlways;
[textField addSubview:btnColor];
return YES;
}
This is how i've created the button in the textField, and for it to only show when editing, as you can see i have it calling clearText however i'm unsure how i can send the current textField name i am in to be cleared in the clearText call.
I know I can do it the hard way, and define it individually for each of my textFields, but i'm sure there is an easier way to go about this, that i just haven't realized.

I suggest subclassing UITextField. This will not allow you to lay out the button in a Storyboard, but in Code or as a .nib file should work. Of course you can use the UITextfield subclass in a storyboard.
Inside the subclass add a UIButton as a subview and in its action method call:
self.text = #""
Let me know if you have any further questions.

Given that your button has been added to the text field as a sub-view you can get to the text field in the buttons superview property:
- (void) clearText:(UIButton*)sender
{
UITextField* textField = (UITextField*)sender.superview;
textField.text = nil;
}

Related

Cannot Alter Custom UIBarButton Item

I am trying to add a custom bar button to my project and I'm having a few problems. First lets go over the requirement for my button, it needs:
- to display a custom font
- to be enabled/disabled
- to have its colour animated based to provide user feedback.
So I first tried connecting a barButtonItem up through the storyboard and I could change the colour and enable disable it. However I could not change the font or add colour animation to it. I want to be able to use the following method which I am already using in the app to animate the colour:
- (void)textFlashTextfieldAnimation:(nonnull UITextField *)view duration:(NSTimeInterval)duration animateToColour:(UIColor*)animationColour textColor:(UIColor*)textColour completion:(void (^)(BOOL finished))completion {
[UIView transitionWithView:view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
view.textColor = animationColour;
} completion:^(BOOL finished) {
[UIView transitionWithView:view duration:2.0f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
view.textColor = textColour;
} completion:completion];
}];
}
Ideally I would be able to change this function to accept a barButtonItem / UIButton so that I could animate it easily. However if I connect the button up through storyboards I cannot access the button's layer so the animation is not possible.
I had started to go about this through code but I've gone down 2 dead ends. Here is a really basic implementation of a barButtonItem:
UIBarButtonItem *myButton=[[UIBarButtonItem alloc] initWithTitle:#"My Custom Button" style:UIBarButtonItemStylePlain target:self action:#selector(/*do something*/)];
[self.navigationItem setRightBarButtonItem:myButton];
Now this will work in the fact that I can use it like a storyboard button however I cannot alter the font or access the button's layer so it is also no good.
I then tried creating a fully custom view for my bar button by creating a UIView and a UIButton and then adding them to a barButtonItem, this can be seen here:
UIFont *barButtonFonts = [UIFont fontWithName:kFont size:16];
//Right Button
//create view
UIView *rightButtonView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 45, 25)];
//create button
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeSystem];
rightButton.backgroundColor = [UIColor clearColor];
rightButton.frame = rightButtonView.frame; //set frame = to view
[rightButton setTitle:NSLocalizedString(#"Save", nil) forState:UIControlStateNormal];
rightButton.titleLabel.font = barButtonFonts;
rightButton.tintColor = [UIColor redColor];
[rightButton addTarget:self action:#selector(actionMethod) forControlEvents:UIControlEventTouchUpInside];
[rightButtonView addSubview:rightButton];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:rightButtonView];
self.navigationItem.rightBarButtonItem = rightBarButton;
Now I have a barButtonItem that will display a custom font however it is has no UI interaction at all. It looks the same when enabled/disabled and when not-highlighted/highlighted. The button works as it should it just doesn't look like it should.
Should I create an outlet to this button somewhere in my code so that I can alter the button when in the view? Is it even possible to alter a button after it has been added to the navigation bar?
If anybody has any suggestions it would be appreciated!
Yeah barbuttonitem isn't modifieable after you added it to the bar. only way i can think is to remove the button and add a new one (with the new characteristics) when user interact with it. I suggest you to use a custom toolbar (like a normal UIView), then add a normal button to it. it would be easier to customize

How to programmatically deselect UITextField

I have a UITextField which I can click on, and edit the contents of. I am running code when the UITextField is pressed by using:
[personalCountryLabel addTarget:self action:#selector(countryPressed) forControlEvents:UIControlEventEditingDidBegin];
This presents another view controller. However, when I click the back button, the UITextField is still selected, so the text runs again, sending me back to the view controller.
I use the code:
textField.enabled = false;
and
textField.enabled = true;
to respectively turn off and on the editing of the UITextField, but doing this in succession does not unselect the UITextField.
How can I therefore programmatically deselect the UITextField (i.e, where the line cursor is no longer blinking).
If I understand what you're asking correctly, you just want:
[textField resignFirstResponder];
/* Programmatically deselect the Uitextfiels below this Code */
UITextField *txtDeselect = [[UITextField alloc]initWithFrame:CGRectMake(self.view.frame.origin.x+20, self.view.frame.origin.y+20, self.view.frame.size.width-40, 40)];
[txtDeselect setBackgroundColor:[UIColor yellowColor]];
[txtDeselect setBorderStyle:UITextBorderStyleRoundedRect];
[txtDeselect setTextAlignment:NSTextAlignmentCenter];
[txtDeselect setText:#"Email"];
txtDeselect.enabled = NO;
[self.view addSubview:txtDeselect];
did you set outlet & delegate of UITextField in your view controller ?
why you use UItextfield for this ?
i recommend you use one of this before presenting new view controller :
option 1 :
[youtextfield resignFirstResponder];
//please sure you outlet connected & ....
you can call this on your viewWillAppear
option 2 :
[self.view endEditing:YES]; // this regularly
happend after present another VC)
you shouldn't use shouldEndEditing

Adding default text to UITextView

I was wondering how to display a default prompt in a UITextView. If I wanted the user to type a description in a text view, the UITextView could have "description" printed in it, and when the user starts to type, it disappears.
For UITextField, there is the placeholderText property, which will display a grayed out text that is removed once the user starts typing.
For UITextView, you can use a custom implementation, such as SZTextView, which implements a similar functionality of a placeholder text.
It wont be a wise idea to use a third party uitextview for placeholder property.
Follow these steps and you will achieve what you need-
set- textview.textcolor=[uicolor greycolor];
textview.text=#"Your initial placeholder text";
Now in -textViewShouldBeginEditing write these lines of codes-
if(textview.color==[uicolor greycolor]){
textview.color=[uicolor blackcolor];
textview.text=#"";
}
Cheers.
The below solution from #svmrajesh isn't complete. You still need to implement an auto-delete functionality so the default text deletes as soon as the user selects the textView.
In my implementation I set the text in the UITextView to lightGrayColor initially so that it looks like default text
[textView setTextColor:[UIColor lightGrayColor]];
Then in the header file I implement the UITextViewDelegate.
#interface YourViewController <UITextViewDelegate>
Then I set the UITextView delegate to self.
[textView setDelegate:self];
Then simply I implement the following delegate method which is fired when the user selects the textView to start typing in their text. The first thing it does is to check if the text color is still set to lightGray.
If it is then the default text is still being displayed, so it is deleted and the textColor is set to black. This simple solution works well for me.
-(void)textViewDidBeginEditing:(UITextView *)textView
{
if(textView.textColor == [UIColor lightGrayColor])
{
textView.textColor = [UIColor blackColor];
textView.text = #"";
}
}
Try this....
For UITextView :
UITextView *myUITextView = [[UITextView alloc] init];
myUITextView.delegate = self;
myUITextView.text = #"placeholder text here...";
For UITextField :
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 150, 200)];
textField.placeholderText = #"Enter your text here";
[self.view addSubview textField];

inputAccessoryView on UIView

It's easy as pie to add an inputAccessoryView on a UITextField, UITextView, or UISearchBar. However, there's no obvious and easy way to add one for your basic UIView as far as I can tell!
I have a UIView subclass that follows the UIKeyInput protocol. It receives keyboard input to do stuff that isn't related to entering text, so I'd rather not force it to subclass the former specified views because it adds bloat and would expose a bunch of properties that don't do anything, plus I'd need to work around the text entry that occurs natively to those classes (more bloat).
However, my UIView does need an input accessory view on its presented keyboard to function correctly.
Are there any simple ways to go about this? Do I have to register as an observer to the UIKeyboardWillShowNotification in my UIView subclass and add a subview, as an accessory view, to it manually?
Did you try simply adding the inputAccessoryView method to your viewController?
I believe it gets called when the keyboard is shown, so you don't actually have to assign one to each textField or view.
- (UIView *)inputAccessoryView
{
if (!inputAccessoryView)
{
CGRect accessFrame = CGRectMake(0.0, 0.0, 768.0, 77.0);
inputAccessoryView = [[UIView alloc] initWithFrame:accessFrame];
inputAccessoryView.backgroundColor = [UIColor blueColor];
UIButton *compButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
compButton.frame = CGRectMake(313.0, 20.0, 158.0, 37.0);
[compButton setTitle: #"Word Completions" forState:UIControlStateNormal];
[compButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[compButton addTarget:self action:#selector(completeCurrentWord:) forControlEvents:UIControlEventTouchUpInside];
[inputAccessoryView addSubview:compButton];
}
return inputAccessoryView;
}

Clear button on UITextView

How can I add a clear button (cross inside a circle) for UITextView like UITextField has?
Based on the answer from GhostRider a more accurate and up to date implementation:
int kClearButtonWidth = 15;
int kClearButtonHeight = kClearButtonWidth;
//add the clear button
self.clearButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.clearButton setImage:[UIImage imageNamed:#"UITextFieldClearButton.png"] forState:UIControlStateNormal];
[self.clearButton setImage:[UIImage imageNamed:#"UITextFieldClearButtonPressed.png"] forState:UIControlStateHighlighted];
self.clearButton.frame = CGRectMake(0, 0, kClearButtonWidth, kClearButtonHeight);
self.clearButton.center = CGPointMake(self.textView.frame.size.width - kClearButtonWidth , kClearButtonHeight);
[self.clearButton addTarget:self action:#selector(clearTextView:) forControlEvents:UIControlEventTouchUpInside];
[self.textView addSubview:self.clearButton];
And the method
- (void)clearTextView:(id)sender{
self.textView.text = #"";
}
You can use this images for the two states of the button:
just make a uibutton and put it on uitextview and set its action for clear text view;
uitextview.frame = (0,0,320,416);
uibutton.frame = (310,0,10,10);
[uibutton setimage:#"cross.png" forcontrolstate:uicontrolstatenoraml];
[uibutton addTarget:self action:#selector(clearButtonSelected:) forControlEvents:UIControlEventTouchUpInside];
-(void)clearButtonSelected{
uitextview=#"";
}
hope you want to clear the text view text when you click on cross button above is help
if not understand then i can send you proper program for that
From product perspective, if you're going to have a clear button, you probably want to use a UITextField instead of a UITextView and UITextField supports a clear button natively - set the clearButtonMode property as such:
UITextField *textfield = ...;
textfield.clearButtonMode = UITextFieldViewModeAlways;
See screenshot:
You could use UITextFieldViewModeWhileEditing to only present the clear button while the user is actively updating the content.
There's nothing built in like there is for the UITextField. You'd have to add the view yourself (probably a UIButton) and place it correctly and also somehow get the text to wrap around it correctly. (And I don't think the latter is really possible.)
Maybe instead you should display a toolbar above the keyboard (or an inputAccessoryView if you're targeting 3.2 and later) that provides a clear button.
For me changing the .frame or the .contentInset properties did not work.
For me the best result came from:
1) adding a UIView to the controller, give it round corners and a border to mimic a UITextView.
self.viewTextBackground.layer.borderColor = [UIColor colorWithRed:171/255.0 green:171/255.0 blue:171/255.0 alpha:1.0].CGColor;
self.viewTextBackground.layer.borderWidth = 1.0f;
self.viewTextBackground.layer.cornerRadius = 9.0f;
2) place UITextView on top of this UIView. Place it so that the borders of the underlying UIView stay visible.
3) give the UITextView round corners:
self.textNote.layer.cornerRadius = 9.0f;
3) Make its width fe. 30pixels less compared to the underlying UIView. You now have space for a clear-button.
4) simply add a UIButton to your controller and place it in the top-right corner of the underlying UIView.
5) change the buttons properties: set its type to 'custom' and set its image to the image of a grey cross.
6) bind an action to the button te clear the UITextView
You can add a clear button like the one in the attached screenshot with minimal coding. Just follow these steps:
Select the storyboard and drag a UIButton into your UITextView
Set the buttons constraints
Assign a title or a background image
Create the button's IBOutlet reference and the action (see onClearPressed(_:) below) for "Touch Up Inside" in the ViewController
Implement the textViewDidChange(_:) UITextViewDelegate delegate method, and make sure to set the button's isEnabled property based on the textfield content, e.g.:
func textViewDidChange(_ textView: UITextView) {
clearButton.isEnabled = !textView.text.isEmpty
}
Implement the onClearPressed(_:) action:
#IBAction func onClearPressed(_ sender: Any) {
textView.text = ""
clearButton.isEnabled = false
}
That's it.

Resources