I want to show UITableView on tapping of UITextView.
key board should not be shown.
the problem is on tapping UITextView both UITableView and keyboard are shown.
I want only table view to be shown. I want to display data got from web service in UITextView which is not editable.on pressing edit button in navigation bar that time on tapping UITextView ,UITableView should be popped up and not keyboard.
My code is below:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
-(void)textViewDidBeginEditing:(UITextView *)textView{
[self.view endEditing:YES];
tableVw=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 500)];
tableVw.dataSource=self;
tableVw.delegate=self;
[self.view addSubview:tableVw];
}
-(void)viewDidLoad{
[super viewDidLoad];
txtVwDescription=[[UITextView alloc]initWithFrame:CGRectMake(10, 270, 300,stringSize.height+10)];
txtVwDescription.backgroundColor=[UIColor clearColor];
txtVwDescription.layer.cornerRadius=5;
txtVwDescription.backgroundColor=[UIColor colorWithRed:0.662745 green:0.662745 blue:0.662745 alpha:0.3];
[txtVwDescription setFont:[UIFont systemFontOfSize:13.0]];
txtVwDescription.contentInset=UIEdgeInsetsMake(0, 0, 0, 0);
[txtVwDescription setUserInteractionEnabled:NO];
txtVwDescription.editable=NO;
txtVwDescription.delegate=self;
[self.view addSubview:txtVwDescription];
}
-(void)edit{
[txtVwDescription setUserInteractionEnabled:YES];
txtVwDescription.editable=NO;
[txtVwDescription resignFirstResponder];
}
you can use UITextViewDelegate's textViewShouldBeginEditing method returning NO, and presenting there the UITableView. In such a way the keyboard should not be presented.
Rather than having to mess with textViewDelegate methods, I find it easier to simply disable editing for the textView and add a gesture recognizer to it like this:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showTableView)];
UITextView *textView = [[UITextView alloc] initWithFrame:....];
textView.editable = NO;
[textView addGestureRecognizer:tapGestureRecognizer];
This way, no keyboard is shown and you don't have to mess around with navigation inside the delegate methods. All you need to do now is handle the tap with the method you provided the recognizer:
- (void)showTableView {
// do stuff here
}
EDIT:
You might want to also consider using a UILabel instead of a UITextView if you are not planning on making it editable at all. You can implement the same gesture recognizer code as well, just add it to the label instead of the textView.
UITextField and UITextView classes has a property named inputView for displaying custom views instead of the default keyboards. The system shows whatever UIView descendant class you set to that property when the textfield/view becomes first responder. So simply add,
UITextView *textView = [[UITextView alloc] initWithFrame:someFrame];
textView.inputView = self.myTableView; //this is your already initialised tableview
Related
I have a UITextView that is created programmatically on viewDidLoad using the method below. Keyboard is shown successfully right after [_answerTextView becomeFirstResponder] is called. And hid if the user enters return(\n) character.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
return YES;
}
After the keyboard is hid by the code above, I'm not able to bring it back anymore by tapping the UITextView again.
I tried showing the keyboard by calling [_answerTextView becomeFirstResponder] on Tap event for the parent UIView and it worked. But that's not what I want.
UITextView is created by the method below;
-(UITextView*)createSurveyTextView{
_answerTextView = [[UITextView alloc]initWithFrame:CGRectMake(0, 0, _optionsStackView.frame.size.width, 200)];
_answerTextView.keyboardType = UIKeyboardTypeDefault;
_answerTextView.text = #"";
_answerTextView.editable = true;
_answerTextView.selectable = true;
_answerTextView.delegate = self;
[_answerTextView becomeFirstResponder];
_answerTextView.backgroundColor = [UIColor whiteColor];
_answerTextView.textColor = [UIColor blackColor];
_answerTextView.layer.cornerRadius = 5;
[_optionsStackView addSubview:_answerTextView];
_answerTextView.font = [UIFont systemFontOfSize:20];
[_answerTextView setReturnKeyType:UIReturnKeyDone];
[_optionsStackView bringSubviewToFront:_answerTextView];
[self bringSubviewToFront:_answerTextView];
[_answerTextView setUserInteractionEnabled:true];
UITapGestureRecognizer *mainViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTextViewTap:)];
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap2:)];
[_answerTextView addGestureRecognizer:mainViewTap];
[self addGestureRecognizer:tap2];
return _answerTextView;
}
I want the UITextView to simply show the keyboard when the user taps on it self. What am I missing?
Edit: I have the same sources in another view, but everything works fine there. The only difference is, here the UITextView is created programmatically.
Edit 2: I got it worked. The _optionsStackView that the UITextView is added as a child is a UIStackView. I tried adding the _answerTextView to the parent UIView and everything works fine now. What would be the problem with the UIStackView?
Your problem very strange in your code.You can explantion why use UITapGestureRecognizer to this UITextView control.How do you think this lead to conflict?
I find your problem where in start,but I create new project to ensure.So I confirm that UITextView already has target with itself.Also you can't to add UITapGestureRecognizer.
What you're doing is almost correct, but just try changing endEditing: to [textView resignFirstResponder]:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
If that doesn't work, then it could be that one of your gestures is preventing the UITextView's own UITapGestureRecognizer from receiving the tap. Try disabling (or comment out the creation of) both of your recognizers to verify that it is the issue. If it is, then you can fix it using the UIGestureRecognizerDelegate methods.
You did not use common way to hide/close the keyboard.
Try this common way:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
return [textField resignFirstResponder];
}
This is a method in the UITextFieldDelegate, use it and remove your code:
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
Edit:
#siburb You are right. My bad.
UITapGestureRecognizer maybe the root cause.
Edit:
#Semih Akbas
Repalce:
[_optionsStackView addSubview:_answerTextView];
To:
[_optionsStackView addArrangedSubview:_answerTextView];
I am trying to make a UILabel that if I click I can edit it. I have a hidden textfield.
Per this answer: How to customize UILabel clickable
I tried the following:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
tapInput = [[UIGestureRecognizer alloc] initWithTarget:self action:#selector(didTapLabel)];
[lblInput setUserInteractionEnabled:YES];
[lblInput addGestureRecognizer:tapInput];
}
-(void)didTapLabel
{
[txtHidden becomeFirstResponder];
}
But my break point inside didTapLabel is not firing. Everything is hooked up correctly on the storyboard.
Use this code, It's worked. Tested.
UILabel * clickMeLbl=[[UILabel alloc] initWithFrame:CGRectMake(75,30,170,30)];
clickMeLbl.text = #"Click Me";
clickMeLbl.font = [UIFont fontWithName:#"Helvetica-Bold" size: 18.0f ];
clickMeLbl.textAlignment = NSTextAlignmentCenter;
clickMeLbl.textColor = [UIColor blackColor];
[self.view addSubview:clickMeLbl];
clickMeLbl.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(didTapLabelWithGesture:)];
[clickMeLbl addGestureRecognizer:tapGesture];
- (void)didTapLabelWithGesture:(UITapGestureRecognizer *)tapGesture {
NSLog(#"Click Me Label Clicked");
}
Try enabling user interaction here for label,Worked for me, and please use UITapGesture instead of UIGesture
And Textfield should be below uilabel because if the textfield is above label then uilabel's user interaction won't be considered
I have a UIView with a UITextField, UIButton and UITable view. The textfield and button compromise a search bar and the results are then loaded into the table view.
I'd like to make it so they keyboard dismisses. If the user taps something when they are editing the text field. My strategy would be to add a gesture recognizer to the UIView, but then gesture recognizer seems to intercept all the touches from the table view and you |tableView:didSelectCellAtIndexPath:| never gets called. Whats interesting (to me at least) is that the UIButton is still tap-able when the user is editing the field even though the UITableView isn't.
I've tried implementing |gestureRecognizer::shouldRecognizeSimultaneouslyWithGestureRecognizer:| to alway return yes, but that doesn't help. I've also tried setting
singleTapRecognizer.cancelsTouchesInView = NO;
which also doesn't help.
I'm happy with the idea of adding and removing the gesture recognizer when the text field calls |textFieldDidBeginEditing:| and |textFieldDidFinishEditing:|, though this feels messy and it still takes two taps to touch a cell when you're editing the text field (one to dismiss they keyboard and remove the recognizer, and one to tap the cell).
Is there a better way?
Relevant code below:
- (void)loadView {
[super loadView];
self.scrollView = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.scrollView.backgroundColor = [FDEColors viewBackgroundColor];
self.view = self.scrollView;
self.searchField = [[UITextField alloc] initWithFrame:CGRectZero];
self.searchField.placeholder = #"What are you looking for?";
self.searchField.backgroundColor = [FDEColors textFieldBackgroundColor];
self.searchField.clipsToBounds = YES;
self.searchField.layer.borderColor = [[FDEColors buttonColor] CGColor];
self.searchField.layer.borderWidth = 1.f;
self.searchField.returnKeyType = UIReturnKeySearch;
self.searchField.delegate = self;
[self.view addSubview:self.searchField];
self.searchButton = [[UIButton alloc] initWithFrame:CGRectZero];
self.searchButton.backgroundColor = [FDEColors buttonColor];
[self.searchButton setTitle:#"Search" forState:UIControlStateNormal];
[self.searchButton addTarget:self
action:#selector(searchPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.searchButton];
self.resultsTableView =
[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
self.resultsTableView.delegate = self;
self.resultsTableView.dataSource = self;
self.resultsTableView.backgroundColor = [FDEColors viewBackgroundColor];
[self.resultsTableView setSeparatorInset:UIEdgeInsetsZero];
self.resultsTableView.layoutMargins = UIEdgeInsetsZero;
[self.resultsTableView registerClass:[FDESearchResultsCell class]
forCellReuseIdentifier:[FDESearchResultsCell reuseIdentifier]];
[self.view addSubview:self.resultsTableView];
self.singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:self.singleTapRecognizer];
}
- (void)dismissKeyboard {
[[self view] endEditing:YES];
}
Try implementing the gesture recognizer's delegate method:
- (BOOL) gestureRecognizer:ShouldReceiveRouch:
In this method, check for the touch's location. If it's inside the tableview, return no, so the tableview can receive the touch. Otherwise, return YES and let the recognizer handle the touch.
Edit: As for the button receiving the touch despite the recognizer's existence, as of iOS6 Apple decided to give buttons and some other controls priority when it comes to recognizing gestures. It only applies to antagonizing gestures though, in your case a single tap. If for example you also had a pan recognizer, the recognizer would have precedence, not the button.
Edit 2:
An example implementation of the method mentioned above:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Determine if the touch is inside the custom subview
if ([touch view] == self.yourTableView){
// If it is, prevent all of the delegate's gesture recognizers
// from receiving the touch
return NO;
}
return YES;
}
i have a UITableViewCell, and inside of it, i have a UITextView with some text, and it must remain scrollable so i can't remove the user interaction in it.
But the problem is, when i tap the screen, this cell must be selectable as well. Since the UITextView is in front of the cell touch area i'm unable to do that.
I've try to place a UITapGestureRecognizer into the UITextView inside the cell class but i don't know which method to call to select the cell, ending on the UITableView delegate (didSelectRowAtIndexPath) in the main class.
Does Anyone can help me with that, or have other ideas how i can sort this out?
Thanks a lot in advance!
//CUSTOM CELL CODE
-(void)awakeFromNib
{
self.backgroundColor = [UIColor clearColor];
self.title.font = [UIFont fontWithName:FONT_MEDIUM size:14];
self.title.textColor = [UIColor colorWithRed:181/255.0 green:181/255.0 blue:179/255.0 alpha:1];
self.text.font = [UIFont fontWithName:FONT_LIGHT_ITA size:13];
self.text.textColor = [UIColor colorWithRed:236/255.0 green:220/255.0 blue:0/255.0 alpha:1];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(touchAction:)];
[self.text addGestureRecognizer:tap];
}
-(void)touchAction:(UITapGestureRecognizer*)sender{
NSLog(#"Touch");
}
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
have you tried this way ?
without disabling textView's user interaction set UITextView's delegate, implement UITextViewDelegate's textViewShouldBeginEditing method like this
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
[self.tableView selectRowAtIndexPath:yourCellIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
return NO;
}
documentation says "When the user performs an action that would normally initiate an editing session, the text view calls this method first to see if editing should actually proceed."
I'm trying to make a UITextView that detects links AND becomes editable when a tap doesn't fall on a link.
The native iphone notes app exhibits this behavior, as does simplenote.
The closest solution I have found is outlined here: http://blog.stevex.net/2012/05/editable-uitextview-with-links/ Using this code:
// Add the tap gesture recogniser to the view.
- (void)configureTextView {
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(textViewTapped:)];
textView.editable = NO;
textView.dataDetectorTypes = UIDataDetectorTypeLink;
[textView addGestureRecognizer:recognizer];
}
// Notification from the recogniser that the UITextView was tapped
- (void)textViewTapped:(UIGestureRecognizer *)recognizer {
UITextView *textView = (UITextView *)recognizer.view;
textView.editable = YES;
[textView becomeFirstResponder];
}
// UITextViewDelegate method
- (void)textViewDidEndEditing:(UITextView *)textView {
textView.editable = NO;
}
The problem with this solution is that it requires a long press to follow a link.