how to do this operation in UITextView (iphone) - iphone

In My textView there is a default value of "First name "
I want to implement such operation in it..
1) it should be shown "first name" firstly
2) when I start editing it should became nil
3)when I am complete with my editing if the field is still nil then it should be shown as "first name" again
can anyone help me with this?
//*This is now what I am doing now**//
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if (first_name.text=#"") {
first_name.text=#"First Name(Required)";
}
// Any new character added is passed in as the "text" parameter
if ([text isEqualToString:#"\n"]) {
// Be sure to test for equality using the "isEqualToString" message
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return FALSE;
}
// For any other character return TRUE so that the text gets added to the view
return TRUE;
return TRUE;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
NSLog(#"textViewShouldBeginEditing");
textView.scrollEnabled=NO;
if (textView == first_name) {
first_name.text=nil;
}
return YES;
}

All the delegate methods you can use to implement this concept can be found in the UITextViewDelegate Protocol Reference.

You need to overlay a UILabel on top of the text view with the text you want, set its userInteractionEnabled to NO and on the text field delegate method shouldBeginEditing you hide the UILabel before returning YES and unhide it on shouldFinishEditing.

Related

Problem with textFieldShouldReturn method when using UITextField along with UITextView

I have a grouped table view that contains 3 sections and each row per section. The first two section rows contains UITextField(Name & Subject are the section titles) and the last one contains UITextView(Message is the section title) because i want to get some data from the user by this controller itself.
The two text fields have the returnKeyType as UIReturnKeyNext. For UITextView, the "return" button is present in keyboard to feed new line. So i used textFieldShouldReturn method to navigate to the next cell by pressing these return type buttons in UIKeyboard.
The next button will work fine with the first text field(Name). Here the problem comes... If i click the Next button of second cell, It goes to the UITextView(last cell) with one line down. That is, the cursor moves one line apart from its original position.
My code is...
-(BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if (textField == nameTextField) {
[subjectTextField becomeFirstResponder];
}
else if(textField == subjectTextField) {
[messageTextView becomeFirstResponder];
}
return YES;
}
What should i do to make this work fine? Thanks in Advance..
While testing a lot of stuff I found a simple yet suitable solution:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ( [textField isEqual: nameTextField] )
{
[nameTextField resignFirstResponder];
[messageTextView becomeFirstResponder];
return NO;
}
return YES;
}
It handles the resigning of the nameTextField itself and returns NO to the request.
Basically what is happening is that when return is tapped you make text view the first responder and the return gets added to the text view. Thats why the cursor goes to the second line. Try doing this in your textViewDidChange: delegate method:
- (void)textViewDidChange:(UITextView *)textView {
if(textView.text == #"\r") {
textView.text = #"";
}

simple question about UITextField and not working secureTextEntry

I have a password field with text "Password" and when user clicks, it gets cleared. Moreover I want to set the type of this textfield as secure but this doesn´t work.
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if ([textField.text isEqualToString:#"Password"] || [textField.text isEqualToString:#"Email"])
{
textField.text = #"";
textField.secureTextEntry = YES;
}
}
I've just had the same problem. I was changing the property from within the textFieldDidBeginEditing: call.
Moving the property change to the textFieldShouldBeginEditing: call fixed the problem. I believe the trick is to change it while the text field isn't the becomeFirstResponder.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if ([textField isEqual:_passwordField]) {
textField.secureTextEntry = YES;
}
return YES;
}
Simply put your text in a placeholder and make your password textfield secure. Your problem will be solved :).
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if ([textField.text isEqualToString:#"Password"] || [textField.text isEqualToString:#"Email"])
{
textField.text = #"";
[textField resignFirstResponder];
textField.secureTextEntry = YES;
[textField becomeFirstResponder];
}
}
it can solve your problem , but it has a big bug. the shit UITextField .
set the property in interface builder or when you initialize textfield remove the line from
-(void)textFieldDidBeginEditing:(UITextField *)textField {
}
I think you should set placeholder text as email or password and pre select the secure text entry from interface builder.That's it...
I realize this is a little old, but in iOS 6 the UITextField "text" is now by default "Attributed" in Interface Builder. Switching this to be "Plain", which is how it was in iOS 5, fixes this problem.
If your keyboard is present, secureTextEntry won't work. Because the UITextInputTraits Protocol doesn't change the textfield if the keyboard shows.
You can dismiss the keyboard, and it will work
[myTextField resignFirstResponder]

textFieldDidBeginEditing: for more than one textfield

I am fairly new to iphone programming and here I am facing some issues. Now in my application, I have two textfields and I want to fire an event while second textfield starts editing. now I am using following function
- (void)textFieldDidBeginEditing:(UITextField *)textField
but the thing is the event is being fired when the first textfield starts editing. It does not wait for the second text field. Is there any way I can use this function for the second textfield or may be somehow could know and pass it the value of the active textfield?
I tried writing the name of the textfield instead of (UITextField *)textField in the function but still the same result.
If I were you , I would set a tag (in Interface Builder) of the second textField to 2, or something similar. Then you can just do this:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField.tag == 2) {
//this is textfield 2, so call your method here
}
}
EDIT: Please do this to see if the method is even called:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(#"The method was called");
}
For Swift 2.2
func textFieldDidBeginEditing(textField: UITextField) {
if textField.tag == 2 {
//this is textfield 2, so call your method here
}
}
That delegate method is gonna get called everytime the editing of ANY text field is started, so it should be you who controls what is done when this happens. I suggest you to do something like:
-(void)textFieldDidBeginEditing: (UITextField *)textField
{
if (textField == mySecondTextField)
{
//Do what you need
}
else
{
//Do nothing
}
}
I hope it helps you!
Utilitize the tag property in Interface Builder to identify your view objects in your application at runtime. It will make life a lot easier, especially when you get ready to localize your application for different languages.
In your header file for your view controller
#define kUsernameField 100
#define kPasswordField 101
#define kStartButton 300
In the view controller implementation file
- (void)textFieldDidBeginEditing:(UITextField *)textField {
switch (textField.tag) {
case kUsernameField:
// do user name stuff
break;
case kPasswordField:
// do password stuff
break;
default:
NSLog(#"No case statement for %#", [textField description]);
break;
}
}
You will find a lot of tutorial out there that use the title field of UIButton to identify them. For example:
- (IBAction)buttonTouchUp:(id)sender {
UIButton *button = (UIButton *)sender;
// don't like
if ([button.currentTitle isEqualToString:#"Start"] == NSOrderedSame) {
// because if localize your for other language then you will have
// include code for those other language
// French: Démarrer
// Spanish: Inicio
// blah blah blah
}
// better
if (button.tag == kStartButton) {
// very simple, no code changes for localization
// blah blah blah
}
}
If you are creating the object with code, you can set the tag:
button.tag = kStartButton;
// or
[button setTag:kStartButton];
You must declare first UITextFieldDelegate in your controller .h
And set the delegate of your text field. ex. myInput.delegate = self;
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:myInput])
{
NSLog(#"test");
}
}
This works perfectly for me.
Have you checked if your second textViews delegate is set to self ? I had the same issue where I had forgotten to set the delegate of other textFields and hence the delegate method was not firing.
Please have a look to my answer in this Question, it's exactly what you're looking for
Objective C: what is a "(id) sender"?

How to prevent user to editing from given range in iPhone textView

I am currently worked on simple textview application in which I need prevent user to write data in textView & after preventing he may be change other value of textview. Below is my code for prevernting user to write into textview.
- (void)textViewDidChange:(UITextView *)textView
{
NSString *textValue=textView.text;
NSInteger intLen=[textValue length];
if(intlen>280){
textView.editable=No;
}
else
{
textView.editable=YES;
if(intLen <=140)
{
intLen=140-intLen;
intSMSValue=1;
lblSmscounter.text=[[NSNumber numberWithInt:intSMSValue]stringValue];
lblCountChar.text=[[NSNumber numberWithInt:intLen] stringValue];
}
if((intLen>140)&&(intLen <=280))
{
intLen=280-intLen;
intSMSValue=2;
lblSmscounter.text=[[NSNumber numberWithInt:intSMSValue]stringValue];
lblCountChar.text=[[NSNumber numberWithInt:intLen] stringValue];
}
}
}
But in my code I am prevent user to write more than 280 bt user caneditable the previous text.
Try delegate method
(BOOL)textView:(UITextView )textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString)text{
}
If the range of editable text is ok, return yes.

Disable button until text fields have been entered?

I have several uitextfields within a view and I would like to disable the uibutton until all the fields have something entered into them. What's the best way of doing this?
Ideally, I'd like to do some basic validation (make sure all entries are numbers) too.
EDIT
Couldn't get the solutions below to quite work. Below is the version that I got working (cobbled together from Brad, Mike, and various other sources)
Use the UITextFieldDelegate
Create textfields in IB, and attach to the relevant IBOutlets - textField1, textField2 etc
Create and hookup the button to its relevant IBOutlet (submitButton) and IBAction (submitAction) in IB. Uncheck enabled in IB.
Create a validate method in the view controller:
-(IBAction)validateTextFields:(id)sender
{
// make sure all fields are have something in them
if ((textField1.text.length > 0) && (textField2.text.length > 0) && (textField3.text.length > 0)) {
self.submitButton.enabled = YES;
}
else {
self.submitButton.enabled = NO;
}
}
Hookup each fields 'Editing Changed' event to the validateTextFields method. (Note: The 'Value Changed' event doesn't appear to work)
Use this delegate method to limit characters (in my case to numbers, and up to one full-stop). This bit is from Erica Sadun btw.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSCharacterSet *cs;
NSString *filtered;
// Check for period
if ([textField.text rangeOfString:#"."].location == NSNotFound)
{
cs = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
// Period is in use
cs = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet];
filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:#""];
return [string isEqualToString:filtered];
}
Voila.
You will want to implement the UITextFieldDelegate Delegate on all of your textfields in a view cOntroller managing your view like so, making sure to validate your textfields after loading your view:
-(void) viewDidLoad {
textField1.delegate = self; //Note if these were created in a xib, you can do this in IB
textField2.delegate = self;
[self validateTextFields];
}
And Implement the textField:shouldChangeCharatersInRage: method to due the validation everytime the textfileds change:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
[self validateTextFields];
return YES;
}
Finally, do the actual validation and enable or disable your button as needed:
-(void) validateTextFields {
if ((textField1.text.length > 0) && textField2.text.length > 0)) {
myUIButton.enabled = YES;
}
else {
myUIButton.enabled = NO;
}
}
Set yourself to be the delegate of the textfields and handle the textFieldDidEndEditing: method. In this method you can do your validation:
- (void)textFieldDidEndEditing:(UITextField *)textField {
myButton.enabled = (myTextField1.text.length && myTextField2.length);
}
I did not like Brad's answer, as you are always one character behind. The last text field you enter text into must have at least two characters because of the way shouldChangeCharactersInRange works. Here is a solution I found to be much more helpful:
Swift:
//This line goes in viewDidLoad
field.addTarget(self, action: #selector(self.validateTextFields), forControlEvents: UIControlEvents.EditingChanged)
func validateTextFields() {
if field.text != "" {
registerButton.enabled = true
} else {
registerButton.enabled = false
}
}
Objective-C:
//This line goes in viewDidLoad
[myTextField addTarget:self
action:#selector(textFieldDidChange)
forControlEvents:UIControlEventEditingChanged];
- (void)textFieldDidChange
{
if ([self.myTextField.text isEqualToString:#""]) {
[self.button setEnabled:NO];
}
else {
[self.button setEnabled:YES];
}
}
The solution also does not require you to resign the most recent field as first responder, which I find to be useful as the button's state will change whenever your text field's text changes from an empty string to text.
A Swift 3 variant based on Jacob's example.
//
// ViewController.swift
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var txtTextField: UITextField!
#IBOutlet weak var btnButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Ensure that only valid changes to txtTextField enable btnButton
txtTextField.addTarget(self, action: #selector(self.validateTextField), for: UIControlEvents.editingChanged)
}
func validateTextField() {
let validValue = txtTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
btnButton.isEnabled = validValue == "" ? false : true
}
}