I am developing an application where user has to write some information. For this purpose I need a UITextField which is multi-line (in general UITextField is a single line).
As I'm Googling I find a answer of using UITextView instead of UITextfield for this purpose.
UITextField is specifically one-line only.
Your Google search is correct, you need to use UITextView instead of UITextField for display and editing of multiline text.
In Interface Builder, add a UITextView where you want it and select the "editable" box. It will be multiline by default.
You can fake a UITextField using UITextView. The problem you'll have is that you lose the place holder functionality.
If you choose to use a UITextView and need the placeholder, do this:
In your viewDidLoad set the color and text to placeholders:
myTxtView.textColor = .lightGray
myTxtView.text = "Type your thoughts here..."
Then make the placeholder disappear when your UITextView is selected:
func textViewDidBeginEditing (textView: UITextView) {
if myTxtView.textColor.textColor == ph_TextColor && myTxtView.isFirstResponder() {
myTxtView.text = nil
myTxtView.textColor = .white
}
}
When the user finishes editing, ensure there's a value. If there isn't, add the placeholder again:
func textViewDidEndEditing (textView: UITextView) {
if myTxtView.text.isEmpty || myTxtView.text == "" {
myTxtView.textColor = .lightGray
myTxtView.text = "Type your thoughts here..."
}
}
Other features you might need to fake:
UITextField's often capitalize every letter, you can add that feature to UITableView:
myTxtView.autocapitalizationType = .words
UITextField's don't usually scroll:
myTxtView.scrollEnabled = false
Ok I did it with some trick ;) First build a UITextField and increased it's size like this :
CGRect frameRect = textField.frame;
frameRect.size.height = 53;
textField.frame = frameRect;
Then build a UITextView exactly in the same area that u made my UITextField, and deleted its background color. Now it looks like that u have a multiple lines TextField !
Besides from the multiple line behaviour, the main difference between UITextView and UITextField is that the UITextView does not propose a placeholder. To bypass this limitation, you can use a UITextView with a "fake placeholder."
See this SO question for details: Placeholder in UITextView.
If you must have a UITextField with 2 lines of text, one option is to add a UILabel as a subview of the UITextField for the second line of text. I have a UITextField in my app that users often do not realize is editable by tapping, and I wanted to add some small subtitle text that says "Tap to Edit" to the UITextField.
CGFloat tapLlblHeight = 10;
UILabel *tapEditLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, textField.frame.size.height - tapLlblHeight - 2, 70, tapLlblHeight)];
tapEditLbl.backgroundColor = [UIColor clearColor];
tapEditLbl.textColor = [UIColor whiteColor];
tapEditLbl.text = #"Tap to Edit";
[textField addSubview:tapEditLbl];
Yes, a UITextView is what you're looking for. You'll have to deal with some things differently (like the return key) but you can add text to it, and it will allow you to scroll up and down if there's too much text inside.
This link has info about making a screen to enter data:
create a data entry screen
'override func viewDidLoad(){
super.viwDidLoad()
YOUR_TEXT_VIEW.textColor = UIColor.gray // YOUR PREFERRED PLACEHOLDER COLOR HERE
YOUR_TEXT_VIEW.text = "YOUR DEFAULT PLACEHOLDER TEXT HERE"
YOUR_TEXT_VIEW.delegate = self
}'
This code block is enough. Please don't forget to set delegate in viewDidLoad or by storyboard just before to use the following extension:
extension YOUR_VIEW_CONTROLLER: UITextViewDelegate {
func textViewDidBeginEditing (_ textView: UITextView) {
if YOUR_TEXT_VIEW.text.isEmpty || YOUR_TEXT_VIEW.text == "YOUR DEFAULT PLACEHOLDER TEXT HERE" {
YOUR_TEXT_VIEW.text = nil
YOUR_TEXT_VIEW.textColor = .red // YOUR PREFERED COLOR HERE
}
}
func textViewDidEndEditing (_ textView: UITextView) {
if YOUR_TEXT_VIEW.text.isEmpty {
YOUR_TEXT_VIEW.textColor = UIColor.gray // YOUR PREFERED PLACEHOLDER COLOR HERE
YOUR_TEXT_VIEW.text = "YOUR DEFAULT PLACEHOLDER TEXT HERE"
}
}
}
use UITextView instead of UITextField
A supplement to h4xxr's answer in the above, an easier way to adjust the height of the UITextField is to select square border style in the attribute inspectors->Text Field. (By default, the border style of a UITextfield is ellipse.)
Reference: Answered Brian in here : How to set UITextField height?
Use textView instead then conform with its delegate, call the textViewDidChange method inside of that method call tableView.beginUpdates() and tableView.endUpdates() and don't forget to set rowHeight and estimatedRowHeight to UITableView.automaticDimension.
There is another option that worked for me:
Subclass UITextField and overwrite:
- (void)drawTextInRect:(CGRect)rect
In this method you can for example:
NSDictionary *attributes = #{ NSFontAttributeName : self.font,
NSForegroundColorAttributeName : self.textColor };
[self.text drawInRect:verticalAlignedRect withAttributes:attributes];
This code will render the text using as many lines as required if the rect has enough space. You could specify any other attribute depending on your needs.
Do not use:
self.defaultTextAttributes
which will force one line text rendering
Related
I need to keep the placeholder after the text, when click on the text box i need to clear only the placeholder and able to type characters.
In this Marissa is the name text and (First Name) is placeholder. Once i start editing placeholder need to clear and start editing complete text.
How can i achieve that?
I have found some similar custom textfield in the below URL. If you find this suitable, you can use it.
TUTORIAL / SOURCE
Please refer below code.
Just copy-paste below code in viewdidload()
textfield.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:#"Yourtext%#",Placehodertext] attributes:#{NSForegroundColorAttributeName: color}];
Assign Delegate of UITextfield to self.
textfield.delegate = self
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
textfield.text = #"Yourtext"
return YES;
}
You can not set place holder along with the text in a textfield.
But there is one alternate for this.
Textfields has something called left view which you can make readOnly view.
Try this :
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
UILabel *textLabel = [[UILabel alloc] initWithFrame:paddingView.bounds];
textLabel.text = #"Marissa";
[paddingView addSubView:textLabel];
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;
Step 1:
Make the text filed attributed form xib and set the "Marisa (First Name)"
and change the color for the (First Name) as grey color .
Step 2:
And in the Textfiled DidBiginEditing method change the textField.text to "Marisa".
This could be achieved in several ways:
Use the attributedText property of UITextField instance to apply a styling for different parts of the text. Here you need to properly define the property each time a user has changed the input by using delegate methods or by observing UIControl Control Events.
If the structure of the text input is fixed and predefined you could use a batch of fields to imitate a more complex/smart field. Here, for example, you need to put two fields beside. One for the last name, second for the first name. Or you can use a combination of UILabel and UITextField if one the part is not editable. Such an approach allows you to configure a separate part of a complex field as you want: different placeholders, fonts, keyboard styles, etc.
Is it possible to align placeholder in the middle of a UITextField? And when we start editing it should it start from left corner of UITextField? I am new to iOS.
Here is the sample code for that.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
txtList.textAlignment = NSTextAlignmentCenter;
}
// This method is called once we click inside the textField
-(void)textFieldDidBeginEditing:(UITextField *)textField{
txtList.textAlignment = NSTextAlignmentLeft;
}
Don't forgot to give delegate of UITextField.
Start by setting textField.textAlignment = NSTextAlignmentCenter. Your best bet is to implement the use of the UITextFieldDelegate protocol to know when the user is tapping inside your text field. Once the user has tapped inside your text field change the property to textField.textAlignment = NSTextAlignmentLeft if you want the alignment to go back to the left. Additionally, using the same protocol, when the user taps out or the focus leaves your text field, set the property back to textField.textAlignment = NSTextAlignmentCenter.
Swift 3.0 ... Swift 5.5
textField.textAlignment = .center
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];
I'm using storyboards for my UI. I was previously using XCode 4.6 and released on iOS 6. I have since updated to iOS 7 using XCode 5 and updated the Storyboard to work nicely with XCode 5. I have one issue though:
UITextView doesn't want to display font changes within code. Text colour changes work fine. Any other property changes are fine. Font, not at all. I was using a custom font, so I checked different fonts with different sizes (i.e. systemFontOfSize:) but that didn't work. The text view only shows the font that's set in the Storyboard. What could I be missing here? Are there any auto-layout constraints that mess with this sort of thing? I had a few issues with constraints during the migration, but as I said, the fonts work fine in iOS 7.
I guess it's something in the Storyboard that I'm missing, as if I create a UIViewController and add a text view in code, it works fine.
I'd put up some code, but I'm not sure it'd help at all in this case.
Even stranger, this only happens on iPhone, not iPad.
If you're setting the font in code and don't want an editable text view, do this:
textView.editable = YES;
textView.font = newFont;
textView.editable = NO;
In my case, it is matter of 'selectable' property of UITextView.
So I checked 'selectable' property of UITextView in Storyboard Editor to set it YES
and later in viewWillAppear set this property to NO.
textview.text = #"some text";
textview.selectable = NO;
The issue was caused by the editable property being false in the Storyboard. I have absolutely no idea why this caused the font to remain unchanged - and only on iOS 6.
For me it's work if you set the text of your UITextView and after set the font (same for color) :
_myTextView.text = #"text";
[_myTextView setFont:[UIFont fontWithName:#"Helvetica Neue" size:18.0f]];
_myTextView.textColor = [UIColor whiteColor];
Thank you for all the answers guys. Issue is still present on iOS9. What i've found out, is that when you set "User Interaction Enabled = false" in the Interface Builder you can leave Editable and Selectable = true and user will not be able to edit a text view.
So, my solution is:
Set User Interaction Enabled = False in IB
Set Editable = True in IB
Set Selectable = True in IB
Configure your text view in whatever way you want.
Code for swift:
textOutlet.editable = true
textOutlet.textColor = UIColor.whiteColor()
textOutlet.font = UIFont(name: "ArialMT", size: 20)
textOutlet.editable = false
Or if you change the text first it magically gets solved
textOutlet.text = "omg lol wtf"
textOutlet.textColor = UIColor.whiteColor()
textOutlet.font = UIFont(name: "ArialMT", size: 20)
I found the font size was being ignored. This was resolved by ticking the checkbox called: Selectable (having selected the UITextView within the storyboard)
This issue only happens when setting Selectable property to FALSE in the Interface Builder.
In case you are required to have the Editable and Selectable properties set to FALSE do it from the CODE and not in the Interface Builder.
Summing up, make Editable and Selectable properties = YES in the Interface Builder and then add the following code in case you need the properties to be FALSE:
_textView.editable = NO;
_textView.selectable = NO;
Hope this helps,
Swift 3 category that worked for me:
extension UITextView {
func setFontAndUpdate(_ font: UIFont?) {
self.font = font
// Font doesn't update without text change
let text = self.text
self.text = nil
self.text = text
}
}
In my case(Developing on Xcode 7.3, iOS 9),
The cause was the order of setting text and font-family/size, not the options of editable or selectable many answers tell there.(and I don't get any storyboard, xib on that Textview.)
If I input like
[myTextView setFont:[UIFont fontWithName:#"HelveticaNeue-Italic" size:20]];
myTextView.attributedText = mAttStr;
then the font's family and size are not changed, but else
when I reverse those two step, it works. Setting text should be ahead of setting font's family/size.
As mentioned by others:
textView.font = UIFont.systemFont(ofSize: 16)
textView.isEditable = false
p.s. no need to first set isEditable as true since it's true by default: a little shorter, a little nicer
In my case, I solved by setting the new font in "viewDidLayoutSubviews".
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.