I am developing an app for my company but i am no expert on obj-C programming language. I've tried to find some answers on the internet but no success at all. The solution to the problem may be simple, but i am unable to solve it.
I want to limit the text so it fits inside the text box. What is happening right now is as i start typing and it flows on the first line forever and do not change drop to the second line when it hits the box boundaries.
otherdetails = [[UITextField alloc] initWithFrame:otherdetailsf];
otherdetails.text = otherdetailstxt;
[otherdetails.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[otherdetails.layer setBorderWidth:2.0];
otherdetails.layer.cornerRadius = 5;
otherdetails.clipsToBounds = YES;
otherdetails.delegate = self;
otherdetails.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
otherdetails.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
Thats what happens when i type a lot on the text field....
How can i solve this problem?
Thanks!!
Use TextViewinstead of text field if you need to support multiple lines of text whenever the text reaches the end of a line.
From Documentation:
The UITextView class implements the behavior for a scrollable,
multiline text region. The class supports the display of text using
custom style information and also supports text editing. You typically
use a text view to display multiple lines of text, such as when
displaying the body of a large text document.
So your code should be:
otherDetails=[[UITextView alloc]initWithFrame:otherdetailsf];
otherDetails.text=#"";
[otherDetails.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[otherDetails.layer setBorderWidth:2.0];
otherDetails.layer.cornerRadius = 5;
otherDetails.clipsToBounds = YES;
otherDetails.delegate = self;
// otherDetails.contentMode=UIControlContentVerticalAlignmentTop;
try this code:
in viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextViewDelegate>
#property (strong,nonatomic)IBOutlet UITextView *mytextview;
#end
in viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize mytextview;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)addTextView
{
[mytextview setText:#"Lorem ipsum dolor sit er elit lamet"];
mytextview.delegate = self;
[self.view addSubview:mytextview];
mytextview.delegate = self;
}
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:
(NSRange)range replacementText:(NSString *)text{
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
}
return YES;}
-(void)textViewDidBeginEditing:(UITextView *)textView{
NSLog(#"Did begin editing");
}
-(void)textViewDidChange:(UITextView *)textView{
NSLog(#"Did Change");
}
-(void)textViewDidEndEditing:(UITextView *)textView{
NSLog(#"Did End editing");
}
-(BOOL)textViewShouldEndEditing:(UITextView *)textView{
[textView resignFirstResponder];
return YES;
}
#end
I have an OpenGL ES app which uses keyboard. I can make the keyboard pop-up on screen when screen is touched. If I am correct, each time I press a key,
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
should be called. But it doesn't. The app was initially a pure OpenGL Mac game, which I am trying to make an iOS version of, so I am not using storyboard. I prefer to do everything programmatically if possible. Here is my code for ViewController.h:
#import <GLKit/GLKit.h>
#import "KeyboardView.h"
#interface ViewController : GLKViewController {
KeyboardView* keyBoard;
}
#end
relevant parts of ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(#"Failed to create ES context");
}
GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
CGRect viewRect = CGRectMake(0, 0, 100, 100);
keyBoard = [[KeyboardView alloc] initWithFrame:viewRect];
[self setupGL];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view addSubview:keyBoard];
[keyBoard becomeFirstResponder];
}
KeyboardView.h:
#import <UIKit/UIKit.h>
#interface KeyboardView : UIView <UIKeyInput, UITextFieldDelegate> {
UITextField *field;
}
KeyboardView.m:
#import "KeyboardView.h"
#implementation KeyboardView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
field = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 10)];
}
return self;
}
- (void)insertText:(NSString *)text {
}
- (void)deleteBackward {
}
- (BOOL)hasText {
return YES;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSLog(#"text: %#", textField.text);
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] < 1) {
return YES;
} else
{
textField.text = [newString length] > 1 ? [newString substringToIndex:1] : newString;
[textField resignFirstResponder];
return NO;
}
}
#end
I need to be able to get each character entered by user while keyboard is active. I most confess, I am a little bit confused. I am not sure if my approach is correct, so I really appreciate your help.
The keyboard text input isn't captured through the UITextField's
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
It is indeed captured through UIKeyInput's
- (void)insertText:(NSString *)text;
I am using the soft keyboard to capture text on my GLKView (OpenGLES) app, and I don't even need any UITextField at all
For reference:
UIKeyInput Reference Doc
EDIT:
You need to call your keyboardview's becomeFirstResponder to show your keyboard and call resignFirstResponder to hide it
You also need to override canBecomeFirstResponder and return TRUE
I have an UIView (named HCTextFieldView) with subviews: UITextField and UILabel above.
UITextField's delegate is equal to self. Delegate methods textFieldDidBeginEditing and textFieldDidEndEditing perform textfield's background highlight effect.
Next I'am using this custom UIView (HCTextFieldView) in my UIViewController. To handle action of 'Next' and 'Previous' buttons in toolbar (attached above textfield's keyboard) I need the same textfield's delegate methods in UIViewController, BUT delegates became overridden.
**#interface HCBaseTextField : UIView <UITextFieldDelegate>**
...
#end
**#implementation HCBaseTextField {}**
...
textField = [[UITextField alloc] initWithFrame:CGRectMake(0, titleLabel.bottom, self.width - 20, self.height - titleLabel.height)];
**textField.delegate = self**;
...
#pragma mark - UITextField delegate
//textFieldBG - UIImageView that act as background
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[textFieldBg setImage:[[UIImage imageWithName:#"btn_vvod_medium_act"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[textFieldBg setImage:[[UIImage imageWithName:#"btn_vvod_medium_norm"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]];
return YES;
}
...
#end
**ViewController : UIViewController**
...
HCTextFieldView *textFieldView = [[HCTExtFieldView alloc] init];
textFieldView.textField.delegate = self;
...
//I need to use this methods too but they override previous in UIView delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.keyboardControls setActiveField:textField];
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self.keyboardControls setActiveField:textView];
}
Set a delegate in HCBaseTextField like
in HCBaseTextField.h add a property
#property (nonatomic, assign) id<UITextFieldDelegate> textFieldDelagate;
and in HCBaseTextField.m
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
....
if (self.textFieldDelagate && [self.textFieldDelagate respondsToSelector:#selector(textFieldShouldBeginEditing:)]) {
[self.textFieldDelagate textFieldShouldBeginEditing:textField];
}
return YES;
}
- (void) textFieldDidBeginEditing:(UITextField *)textField {
....
if (self.textFieldDelagate && [self.textFieldDelagate respondsToSelector:#selector(textFieldDidBeginEditing:)]) {
[self.textFieldDelagate textFieldDidBeginEditing:textField];
}
}
... //Other delegate methods if needed
and in ViewController : UIViewController
...
HCTextFieldView *textFieldView = [[HCTExtFieldView alloc] init];
textFieldView.textFieldDelagate = self;
...
and implement delegate methods.
- (void) textFieldDidBeginEditing:(UITextField *)textField {
....
//Do the stuff
}
I created a UITextField programmatically making the UITextField a property of the viewController. I need to dismiss the keyboard with the return and the touch on the screen. I was able to get the screen touch to dismiss, but pressing return is not working.
I've seen how to do it with storyboards and by allocating and initializing the UITextField object directly without creating it as a property. Possible to do?
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (strong, atomic) UITextField *username;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
self.username = [[UITextField alloc] initWithFrame:CGRectMake(100, 25, 80, 20)];
self.username.placeholder = #"Enter your username";
self.username.backgroundColor = [UIColor whiteColor];
self.username.borderStyle = UITextBorderStyleRoundedRect;
if (self.username.placeholder != nil) {
self.username.clearsOnBeginEditing = NO;
}
_username.delegate = self;
[self.view addSubview:self.username];
[_username resignFirstResponder];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"touchesBegan:withEvent:");
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
#end
The simple way is to connect the delegate of UITextField to self (self.mytestField.delegate = self) and dismiss the keyboard in the method textFieldShouldReturn using [textField resignFirstResponder];
Another way to dismiss the keyboard is the following:
Objective-C
[self.view endEditing:YES];
Swift:
self.view.endEditing(true)
Put [self.view endEditing:YES]; where you would like to dismiss the keyboard (Button event, Touch event, etc.).
Add a delegate method of UITextField like this:
#interface MyController : UIViewController <UITextFieldDelegate>
And set your textField.delegate = self; then also add two delegate methods of UITextField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
// It is important for you to hide the keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
simply use this in swift to dismiss keyboard:
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
Swift 3
UIApplication.shared.sendAction(#selector(UIResponder.resign‌​FirstResponder), to: nil, from: nil, for: nil)
//Hide keyBoard by touching background in view
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
SWIFT 4:
self.view.endEditing(true)
or
Set text field's delegate to current viewcontroller and then:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Objective-C:
[self.view endEditing:YES];
or
Set text field's delegate to current viewcontroller and then:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
In the App Delegate, you can write
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:YES];
}
use this way, you can don`t write too much code.
Try to get an idea about what a first responder is in iOS view hierarchy. When your textfield becomes active(or first responder) when you touch inside it (or pass it the messasge becomeFirstResponder programmatically), it presents the keyboard. So to remove your textfield from being the first responder, you should pass the message resignFirstResponder to it there.
[textField resignFirstResponder];
And to hide the keyboard on its return button, you should implement its delegate method textFieldShouldReturn: and pass the resignFirstResponder message.
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Here's what I use in my code. It works like a charm!
In yourviewcontroller.h add:
#property (nonatomic) UITapGestureRecognizer *tapRecognizer;
Now in the .m file, add this to your ViewDidLoad function:
- (void)viewDidLoad {
[super viewDidLoad];
//Keyboard stuff
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapRecognizer];
}
Also, add this function in the .m file:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
For a group of UITextViews inside a ViewController:
Swift 3.0
for view in view.subviews {
if view is UITextField {
view.resignFirstResponder()
}
}
Objective-C
// hide keyboard before dismiss
for (UIView *view in [self.view subviews]) {
if ([view isKindOfClass:[UITextField class]]) {
// no need to cast
[view resignFirstResponder];
}
}
To dismiss a keyboard after the keyboard has popped up, there are 2 cases,
when the UITextField is inside a UIScrollView
when the UITextField is outside a UIScrollView
2.when the UITextField is outside a UIScrollView
override the method in your UIViewController subclass
you must also add delegate for all UITextView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
In a scroll view, Tapping outside will not fire any event, so in that case use a Tap Gesture Recognizer,
Drag and drop a UITapGesture for the scroll view and create an IBAction for it.
to create a IBAction, press ctrl+ click the UITapGesture and drag it to the .h file of viewcontroller.
Here I have named tappedEvent as my action name
- (IBAction)tappedEvent:(id)sender {
[self.view endEditing:YES]; }
the abouve given Information was derived from the following link, please refer for more information or contact me if you dont understand the abouve data.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
I know this have been answered by others, but i found the another article that covered also for no background event - tableview or scrollview.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
Since the tags only say iOS i will post the answer for Swift 1.2 and iOs 8.4, add these in your view controller swift class:
// MARK: - Close keyboard when touching somewhere else
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
// MARK: - Close keyboard when return pressed
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
return true
}
// MARK: -
Also do not forget to add UITextFieldDelegate in the class declaration and set your text fields delegate to self (the view).
IN Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
OR
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == yourtextfieldName
{
self.resignFirstResponder()
self.view.endEditing(true)
}
}
First you need to add textfield delegete in .h file. if not declare
(BOOL)textFieldShouldReturn:(UITextField *)textField this method not called.so first add delegate and write keyboard hide code into that method.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
try this one..
So here's what I did to make it dismiss after touching the background or return. I had to add the delegate = self in viewDidLoad and then also the delegate methods later in the .m files.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (strong, atomic) UITextField *username;
#end
.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
self.username = [[UITextField alloc] initWithFrame:CGRectMake(100, 25, 80, 20)];
self.username.placeholder = #"Enter your username";
self.username.backgroundColor = [UIColor whiteColor];
self.username.borderStyle = UITextBorderStyleRoundedRect;
if (self.username.placeholder != nil) {
self.username.clearsOnBeginEditing = NO;
}
self.username.delegate = self;
[self.username resignFirstResponder];
[self.view addSubview:self.username];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
Simply use this in Objective-C to dismiss keyboard:
[[UIApplication sharedApplication].keyWindow endEditing:YES];
Add Delegate : UITextFieldDelegate
#interface ViewController : UIViewController <UITextFieldDelegate>
and then add this delegate method
// This should work perfectly
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view.subviews enumerateObjectsUsingBlock:^(UIView* obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UITextField class]]) {
[obj resignFirstResponder];
}
}];
}
when you using more then one textfield in screen
With this method you doesn't need to mention textfield every time like
[textField1 resignFirstResponder];
[textField2 resignFirstResponder];
Swift 2 :
this is what is did to do every thing !
close keyboard with Done button or Touch outSide ,Next for go to next input.
First Change TextFiled Return Key To Next in StoryBoard.
override func viewDidLoad() {
txtBillIdentifier.delegate = self
txtBillIdentifier.tag = 1
txtPayIdentifier.delegate = self
txtPayIdentifier.tag = 2
let tap = UITapGestureRecognizer(target: self, action: "onTouchGesture")
self.view.addGestureRecognizer(tap)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
if(textField.returnKeyType == UIReturnKeyType.Default) {
if let next = textField.superview?.viewWithTag(textField.tag+1) as? UITextField {
next.becomeFirstResponder()
return false
}
}
textField.resignFirstResponder()
return false
}
func onTouchGesture(){
self.view.endEditing(true)
}
If you don't know current view controller or textview you can use the Responder Chain:
UIApplication.shared.sendAction(#selector(UIView.endEditing(_:)), to:nil, from:nil, for:nil)
for swift 3-4 i fixed like
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
just copy paste anywhere on the class. This solution just work if you want all UItextfield work as same, or if you have just one!
I have a very simple RootView Controller ->Detail View Controller, to display a list of core data object and show details on a selected object in the DetailViewController.
The DetailViewController is a UITableView with custom UITableViewCell that has a UITextField to allow user edits.
I am able to display the table, able to edit the text field and so on. However, I am not sure how to actually update the manage object once the user chooses the Done button or cancel the changes upon a Cancel button action.
I understand I can probably achieve this by using a EditViewController, that can be used to edit one property at a time. But, I am interested in a solution where I could support inline editing in the DetailViewController. Any suggestions would be very helpful.
Thanks,
Custom UITableView Cell code
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
_textField = [[UITextField alloc] initWithFrame:CGRectZero];
[_textField setTextAlignment:UITextAlignmentLeft];
[_textField setReturnKeyType:UIReturnKeyDone];
[_textField setClearButtonMode:UITextFieldViewModeWhileEditing];
[_textField setDelegate:self];
[[self contentView] addSubview:_textField];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void) layoutSubviews {
[super layoutSubviews];
CGRect contentRect = [self.contentView bounds];
// In this example we will never be editing, but this illustrates the appropriate pattern
if ([self isEditing]) {
self.textLabel.frame = CGRectZero;
self.textField.frame = CGRectMake(contentRect.origin.x + kCellLeftOffset, kCellTopOffset, contentRect.size.width - kCellLeftOffset, kCellHeight);
}
else {
CGRect frame = CGRectMake(contentRect.origin.x + kCellLeftOffset, kCellTopOffset, 90, kCellHeight);
CGRect textFrame = CGRectMake(frame.origin.x + frame.size.width + kCellLeftOffset, kCellTopOffset, 180, kCellHeight);
self.textLabel.frame = frame;
self.textField.frame = textFrame;
}
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (!editing)
[_textField resignFirstResponder];
}
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
return [self isEditing];
}
The text editing should really be handled in a controller rather than a view. Your custom cell is a view, the appropriate place to put the text field delegate methods would be the detail view controller.
Here is your solution:
Pass the managedObjectModel of your root view controller to your detail view controller as a property. Do the same with the managed object to be edited.
In the delegate methods of your text field, update the object's properties as appropriate
- (void)textFieldDidEndEditing:(UITextField *)textField {
self.managedObject.textAttribute = textField.text;
}
Finally, in your handlers of the Done and Cancel buttons, save or discard the changes:
-(void)cancel {
[self.managedObjectContext rollback];
[self dismissModalViewControllerAnimated:YES]; // or pop
}
-(void)done {
[self.managedObjectContext save:nil]; // better use proper error handling
[self dismissModalViewControllerAnimated:YES]; // or pop
}