Entered text not showing in UITextView - ios

I have an app i'm trying to port over to iOS 7. As there are no longer any textfields in iOS 7 UIAlertViews. (See here) I have to resort to using 2 UIViews managed by 1 ViewController. I didn't use nib files and just program the UI from code.
When the app is started, the second UIView is stacked on top of the first one, it has a UITextField that takes in a user input. This code works in iOS 7 but does not work on iOS 6 devices.
In an iOS 6 device, when I tap on the textfield in the 2nd UIView, the keyboard appears. However when I enter something into the textfield, no characters appear. I even tried to NSLog the characters entered by the keyboard and got NULL which means no text is entered!
The code is as follows for the primary ViewController:
//View1 : UIView
View1 *aView1;
[aView1 initWithFrame:CGRectMake(20,40,280,200) title:promptMsg]
[self.view addSubview:aView1];
Inside the View1.m:
(id)initWithFrame:(CGRect) aRect title:(NSString*) promptStr{
self = [super initWithFrame:aRect];
UITextField *userField = [[UITextField alloc] initWithFrame:CGRectMake(x,y,a,b)];
[self addSubview:userField];
Does any know what has changed in iOS 7 that 'allows' this behaviour? IS it a bug in iOS 7 or the SDK?

The problem is in your code i did not see any text you are setting, you are just allocating for example refer below:-
(id)initWithFrame:(CGRect) aRect title:(NSString*) promptStr{
self = [super initWithFrame:aRect];
UITextField *userField = [[UITextField alloc] initWithFrame:CGRectMake(x,y,a,b)];
userField.text=#"yourText"; // here setting the text
[self addSubview:userField];
}

Related

How to disable keyboard when clicking a UITextField in iOS?

I am currently developing a prototype that I want to do user testing on desktop first before loading to iPad.
I am looking for solutions to disable the keyboard after clicking a textfield. That means after clicking a textfield, user is able to enter information from the macbook keyboard directly, and the virtual keyboard that automatically shows up in the simulator will not appear. I have been through a lot of tutorials but they are all dismissing the keyboard after user entry; that is not what I am looking for. How should I hide the keyboard?
Thanks so much!
Use this:
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
myTextField.inputView = dummyView; // Hide keyboard, but show blinking cursor
It works for UITextField and UITextView and they need to be set to editable.
What you did Here:
You created a dummy view of width=hight=0, & assigned it as the inputView of your textField.
How It works:
Instead of showing default, keyboard, now, the viewController is showing DummyView as inputView for your UITextField. As DummyView has Width=height=0, You will not see anything on the screen :)
Here is another answer which I found the same hack but with little additional supportive code snippet to hide the blinking cursor too.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO; // Hides both keyboard and blinking cursor.
}
I needed this to be done for a Quantity text field where I increase/decrease the quantity using a UIStepper view. So I needed the keyboard to be hidden always.
This will set the inputView of your textField to, basically, an empty UIView with no frame.
self.theTextField.inputView = [[UIView alloc] initWithFrame:CGRectZero];

Make UITextView parent be its own inputAccessoryView

I'm trying to achieve a similar keyboard interaction that Messages has in iOS 7. I have a UIView which contains a UITextView, and when the user selects it to start typing, I want to make this UIView the inputAccessoryView. This would take care of the animation for me, as well as the new UIScrollView keyboard dismiss interaction in iOS 7.
When the UITextView begins editing, I'm trying to set its inputAccessoryView to its parent UIView (which is already in the view hierarchy). The keyboard appears but not with an accessory view.
I've read some people are using a duo of UITextFields to make this work, but that seems like a bad way to achieve this.
Any suggestions?
A much easier solution is to make your input field the input accessory view of your view controller:
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (UIView *)inputAccessoryView
{
return self.yourInputField;
}
The view will be on screen at the bottom of the screen and when it becomes first responder in response to a user tapping it, the keyboard will be presented. The view will be animated such that it remains immediately above the keyboard.
The only way to get this to work is via a second text field. The idea is to make it a subview but not visible (due to crazy rect). You then switch firstResponder back and forth between it and the real text field while its getting delegate methods. I created a some one viewController test project and did this (you can copy paste and verify behavior with about 2 minutes of time):
#implementation ViewController
{
UITextField *field;
UITextField *dummyView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
field = [[UITextField alloc] initWithFrame:CGRectMake(0, 460, 320, 20)];
field.borderStyle = UITextBorderStyleRoundedRect;
field.delegate = self;
//field.inputAccessoryView = field;
field.text = #"FOO";
[self.view addSubview:field];
dummyView = [[UITextField alloc] initWithFrame:CGRectMake(0, 40000, 320, 20)];
dummyView.delegate = self;
[self.view addSubview:dummyView];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField == field && textField.superview == self.view) {
[field removeFromSuperview];
dummyView.inputAccessoryView = field;
[dummyView becomeFirstResponder];
}
return YES;
}
#end
I should add I've used this technique in shipping apps since iOS 4.
EDIT: So a couple of other ideas:
1) To make the glitch when the keyboard starts moving look a little better, you could take a snapshot of your textView, put that into a UIImageView, and when you remove the textView from the primary view, replace it with the UIImageView. Now the appearance is the same. Add an animation for the image so that noting happens for 50 ms, then the alpha goes to 0. Add a similar animation to your real textview, so that it has an alpha of 0 for 50 ms, then it goes to 1. You may be able to tweak this so the transition is good (but not great).
2) The way apple probably does this is to get the animation curve and timing from the keyboard moving notification. In this case they would add a accessory view with 0 height at first, and animate the textField so its tracking the keyboard, but above it. Both moving same distance at the same time. At the end of the animation, the textField is pulled out of self.view, the accessory view has its frame changed to have the height of the textField, and the textField is placed as a subview of the accessory container view. This should work but yeah, its a bit complex to do. If you want someone to code it for you offer a 100 pt bounty. You still need the dummy text field for when you go and move the textField at the end, since when you take it out of its containing view it will resign first responder. So at the end, you make the dummy field the first responder, move the textfield, then make the real textfield the first responder again.
This actually works best if you don't use .inputAccessoryView at all and instead just animate the position of the parent UIView as the keyboard opens and closes. Here is an answer describing the process step-by-step with all the code.

Changing the inputview property of a UITextView from a custom view to nil leads to a crash

I believe I've come across a bug in iOS 7. When a UITextView is contained in a modal view, having its inputview property changed from a custom view to nil (in order to bring back the system keyboard) will cause the app to crash after the modal view is dismissed.
This crash only occurs under iOS 7. Previous versions of iOS did not exhibit this problem.
I wrote a small sample app to demonstrate the problem. Compile the launch the app and do the following:
Tap the button "Show TextView". This will present a modal
ViewController containing a UITextView and three buttons.
Tap the button "Set inputview to emptyView". This will create an
empty UIView and assign it to the inputview property of the
UITextView.
Tap the button "Set inputview to nil". This will assign nil to the
inputview property of UITextView. This is done in order to show the
system keyboard.
Tap the button "Dismiss ViewController". This will dismiss the view
controller to return to the original view controller.
As soon as the ViewController is dismissed, the app crashes immediately. The crash log sometimes, but not always, refers to an unrecognized selector being sent to an object. The object's type is different every time the crash is reproduced.
Has anyone else come across this sort of bug?
I'm sorry, I'm not exactly understand you.
Here is a solution that does not lead to the crash.
UIView* emptyView;
-(IBAction)setToEmpty:(id)sender {
[self.textView resignFirstResponder];
if (emptyView == nil)
emptyView = [[UIView alloc] initWithFrame:CGRectZero];
self.textView.inputView = emptyView;
[self.textView becomeFirstResponder];
// emptyView = nil; // If you comment out the this line, the app will crash
}
If you enable zombie objects, you can see the following error:
CrashTest[16706:a0b] * -[UIView
_overrideInputViewNextResponderWithResponder:]: message sent to deallocated instance 0x8e88680
ARC in ios7 works in a different way. Apparently you can not release the object, which was firstResponder, before closing mainView.
#implementation NoKbTextField
static UIView *customInput;
- (UIView *) inputView {
if (customInput == nil) {
customInput = [[UIView alloc] init];
customInput.backgroundColor = [UIColor clearColor];
}
return customInput;
}
Exactly the same problem, which eat me 4 hours.
For some reason we do not use ARC, so in the usually way, we should release the view, but the truth is if you release the view, it will crash:
[UIView _overrideInputViewNextResponderWithResponder:]: message sent to deallocated instance 0x8e88680
Only tested in iOS 5.0.1 and 7.0, 5.0.1 is just fine.

UITextView link detection in iOS 7

I have a UITextView which is managed via Interface Builder. As data detection I have "Links" checked. In iOS 6 everything is working fine and links are highlighted and are clickable. In iOS 7 though, all links remain just plain text. The editable and selectable checkboxes are unchecked.
What may be of concern is that the UITextView is a subview of a container view which is again inside a UIScrollView.
It seems that in iOS 7 link detection only works if the UITextView is selectable. So making my UITextView not selectable stopped the the link detection from working.
I also tested this in iOS 6 and I can confirm that in iOS 6 the link detection works fine even with the UITextView not being selectable.
I was having some problems with phone number detection today. It seemed like the UITextView would retain old phone numbers and keep text highlighted after I had set the text to something else.
I found that if I setText:nil before setting the text to the new string, it would reset the textview, and phone numbers would highlight as normal. I'm wondering if this is some kind of bug with UITextView in iOS 7.0
Either way, this did work for me.
When iOS7 first came out this plagued me and I found an answer in this thread (setting the text attribute of the UITextView to nil before setting the actual value did the trick). Then suddenly, the problem (for me it was the entire string being highlighted as a link) cropped back up (assumedly due to an iOS update).
What finally did the trick for me was to stop using the text attribute and set the attributedText. Once I did this, the need for setting fonts/scrolling/selectable/editable/etc. programmatically, disappeared. I defined my UITextView in IB, set the values as I wanted (not scrollable, not editable, selectable, detecting links and phone numbers) and then built an attributed string and set:
myUITextView.attributedString = myAttributedString;
And suddenly everything worked as expected. Hope this helps someone else down the road.
I had the same issue and disabling scrolling on the UITextView activates the link detection on load rather than only working once the user has interacted with the textview. The UITextView also had to be selectable and non-editable.
detailTextView.scrollEnabled = NO;
detailTextView.editable = NO;
detailTextView.selectable = YES;
Being selectable or having scroll enabled isn't necessary on iOS6.
Another thing to check is that userinteraction is enabled on the cell and content view of the cell, otherwise the link won't be clickable.
Check These Lines must be added to use data detector property of textview in UItableView cell.
txtvwMsgText.userInteractionEnabled = YES;
txtvwMsgText.dataDetectorTypes = UIDataDetectorTypeLink;
txtvwMsgText.scrollEnabled = NO;
txtvwMsgText.editable = NO;
txtvwMsgText.selectable = YES;
You should check out NSDataDetector.
You can use this to find and deal with different data (links, phone numbers and more). Have a look on this site:
http://nshipster.com/nsdatadetector/
You can also use the dataDetectorTypes property of UITextView to set what you want to detect in code. May just be a storyboard transition problem for you.
textView.dataDetectorTypes = UIDataDetectorTypeLink;
Be aware, that your textview will only recognize the links if not editable!
Here is a nice tutorial on how to make an editable UITextView with `link detection``
Editable UITextView with link detecion
I've not experienced any problems with that solution since now.
The trick is a GestureRecognizer forwaring touches and enabling/disabling the editing.
You could apply the same thing with the selectable / not selectable issue on iOS7
After few tests, I found solution.
If you want links active and you don't want selection enabled, you need to edit gestureRecognizers.
For example - there are 3 LongPressGestureRecognizers. One for click on link (minimumPressDuration = 0.12), second for zoom in editable mode (minimumPressDuration = 0.5), third for selection (minimumPressDuration = 0.8). This solution removes LongPressGestureRecognizer for selecting and second for zooming in editing mode.
NSArray *textViewGestureRecognizers = self.captionTextView.gestureRecognizers;
NSMutableArray *mutableArrayOfGestureRecognizers = [[NSMutableArray alloc] init];
for (UIGestureRecognizer *gestureRecognizer in textViewGestureRecognizers) {
if (![gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
[mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
} else {
UILongPressGestureRecognizer *longPressGestureRecognizer = (UILongPressGestureRecognizer *)gestureRecognizer;
if (longPressGestureRecognizer.minimumPressDuration < 0.3) {
[mutableArrayOfGestureRecognizers addObject:gestureRecognizer];
}
}
}
self.captionTextView.gestureRecognizers = mutableArrayOfGestureRecognizers;
Tested on iOS 9, but it should work on all versions (iOS 7, 8, 9).
I hope it helps! :)
I've found the trick, this works in iOS 7!
You have to set the UITextView selectable in your xib or programmatically
self.yourTextView.selectable = YES;
and then you have to disable scrolls and enable again after set your text.
self.yourTextView.scrollEnabled = NO;
[self.yourTextView setText:contentString];
self.yourTextView.scrollEnabled = YES;
So using a UITextView keeping it enabled, selectable, not scrollable & links detectable is not as simple as it seems. I encountered this in iOS 8. So my solution was to do something like this in viewDidLoad and then set editable property to NO when textBox editing is done(usually would be a method like doneIsTapped). The trick here is to set editable property to NO after setting text value to textview is completed. This will enable links in the UITextview.
- (void)viewDidLoad
{
[super viewDidLoad];
self.txtViewComment.editable = YES;
self.txtViewComment.selectable = YES;
self.txtViewComment.dataDetectorTypes = UIDataDetectorTypeLink;
self.txtViewComment.scrollEnabled = NO;
}
and
- (IBAction)doneIsTapped:(id)sender
{
self.txtViewComment.text = #"set text what ever you want";
self.txtViewComment.editable = NO;
}
this made the links enabled in textview. Also I would recommend not to use story board at this time(or until apple fixes this problem) and just use code to avoid any unnecessary confusion. Hope this help.
Deactivating UITextViews scrolling ability did the trick for me in a similar setup.
Changing the Tint color to other color actually works.
However if selectable enable the tint will also be the same color.
Make the scrolling property of UITextView to No. it will work...
Self.textView.ScrollingEnable = NO;
None of the above worked for me, instead I did this:
[self.textView setDataDetectorTypes:UIDataDetectorTypeNone];
[self.textView.setTextColor:[UIColor whiteColor]];
[self.textView setDataDetectorTypes:UIDataDetectorTypeNone];
I did this with my textview that was supposed to detect all types, and which had non detected color set to white. You can change the code to represent your proper color and link types to detect.
While this thread is old, I didn’t see an answer that worked for me with Swift, so here goes for Swift 2.2
textView.dataDetectorTypes = UIDataDetectorTypes.Link
textView.selectable = true
This workaround works for me:
textView.selectable = YES;
textView.delegate = self;
- (void) textViewDidChangeSelection:(UITextView *)textView;
{
NSRange range = NSMakeRange(NSNotFound, 0.0);
if ( range.length && !NSEqualRanges(range, textView.selectedRange) ) {
textView.selectedRange = range;
}
}
If you are adding UITextview programmatically just add below lines:
_textView.userInteractionEnabled = YES;
_textView.dataDetectorTypes = UIDataDetectorTypeLink;
_textView.scrollEnabled = NO;
_textView.editable = NO;
This worked for me.

ios adding custom inputView

I'm stuck on a concept in iOS that I can't seem to understand, no matter how much I read about it. I'm trying to override the standard iOS number pad with a custom design. When the user touches the UITextField, I want the custom inputView to reveal instead of the standard number pad.
I created an separate .h/.m/.xib ViewController class for my custom inputView called "customInputViewController" Right now, it's just a dark background and one button that obscures about half of the screen when the UITextField is touched (similar to the number pad, but it just looks different). My implementation fails when I click the one button in my custom inputView -- iOS throws an EXC_BAD_ACCESS error.
This is how I load the .xib file at runtime and attach the custom inputView to the UITextField object:
UIViewController *v = [[customInputViewController alloc] initWithNibName:#"customInputDesign" bundle:nil];
myTextInput.inputView = v.view;
In the .xib file of the custom inputView, I set the File's Owner to be "customInputViewController" and I created an (IBAction) method and attached it to a UIButton. When that button is clicked, the (IBAction) is set up to send an NSLog(#"Button Clicked") message. Nothing special. It's just a simple boilerplate implementation that continues to throw an error.
Maybe I'm doing this entirely wrong. Can anyone provide a simple example?
The view v.view is retained as the inputView property is defined as (readwrite, retain). However, if you release your customInputViewController v somewhere before the input button is clicked, you will get a crash (EXC_BAD_ACCESS)
You can try this in your main controller:
- (IBAction) keyboardButtonClicked
{
NSLog(#"keyboard Button Clicked");
}
- (void) viewDidLoad
{
// do your stuff here ...
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)]; // add autorelease if you don't use ARC
v.backgroundColor = [UIColor darkGrayColor];
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setTitle:#"Test button" forState:UIControlStateNormal];
[b addTarget:self action:#selector(keyboardButtonClicked) forControlEvents:UIControlEventTouchUpInside];
b.frame = CGRectMake(80, 25, 160, 50);
[v addSubview:b];
myTextInput.inputView = v;
}
Should work fine ...
First of all, Take a look at this
The UIKit framework includes support for custom input views and input
accessory views. Your application can substitute its own input view
for the system keyboard when users edit text or other forms of data in
a view. For example, an application could use a custom input view to
enter characters from a runic alphabet. You may also attach an input
accessory view to the system keyboard or to a custom input view; this
accessory view runs along the top of the main input view and can
contain, for example, controls that affect the text in some way or
labels that display some information about the text.
To get this feature if your application is using UITextView and
UITextField objects for text editing, simply assign custom views to
the inputView and inputAccessoryView properties. Those custom views
are shown when the text object becomes first responder...
Actually i don't need to mention all this mess to you, but there is an interesting reason for mentioning this, from the first sentence i am mentioning view-view-view, but you are making the input view in a separate view controller and you are trying to assign it as an input view of your textfield and init shouldn't be creating the view, loadView does that. Calling the view getter (v.view) when view is nil will cause loadView to be invoked.Thats why it is crashing with EXC_BAD_ACCESS.
Source : Text, Web, and Editing Programming Guide for iOS

Resources