I would like to intercept a touch on a UITextField, for instance when I first load it I give it a #selector() to load a different method instead of the delegate stuff?
This is my attempt:
descriptionText = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 25.0, infoView.frame.size.width - 20, 100.0)];
descriptionText.backgroundColor = [UIColor whiteColor];
descriptionText.textColor = [UIColor blackColor];
descriptionText.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
descriptionText.userInteractionEnabled = YES;
[descriptionText addTarget:self action:#selector(loadInfoView:) forControlEvents:UIControlEventTouchUpInside];
descriptionText.font = [UIFont fontWithName:#"Helvetica" size:15];
// show view
[infoView addSubview:descriptionText];
However when I debug the method:
- (void)loadInfoView
{
NSLog(#"load other view here");
}
Your problem is in the forControlEvents:: try UIControlEventEditingDidBegin
[descriptionText addTarget:self action:#selector(loadInfoView:) UIControlEventEditingDidBegin];
Your #selector(loadInfoView:) is also wrong if you have - (void)loadInfoView
or #selector(loadInfoView:) and - (void)loadInfoView: (id) sender
or #selector(loadInfoView) and - (void)loadInfoView
However, why you don't use the UITextFieldDelegate?
.m
#interface ViewController () <UITextFieldDelegate>
#property (strong, nonatomic) UITextField *descriptionText;
#end
Remember to:
self.descriptionText.delegate = self;
Then:
-(void) textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == self.descriptionText)
{
[self loadInfoView];
}
}
Keyboard:
If you don't want to show the keyboard you need to add a [descriptionText resignFirstResponder];
I'm not sure you can get actions to be called on a text field on touch like you want.
If that doesn't work, why don't you attach a tap gesture recognizer to your text field?
Related
I am new in iOS and I am facing problem regarding to get the value from custom table view cell to view controller. I am using rate view for rating and I am checking if value of rate is less then 3 then it show have to enter text in the text view and I want to get value in view controller
My code is like this
CustomTableviewcell.h
#interface NextTableview : UITableViewCell<RateViewDelegate,UITextViewDelegate>
{
NSString *StatusValue;
UILabel *lbl;
}
#property(nonatomic,strong) IBOutlet UILabel *staticlbl;
#property(nonatomic,strong) IBOutlet UITextView *commenttxtview;
#property(nonatomic,strong) IBOutlet UILabel *Kpiidlbl;
#property (weak, nonatomic) IBOutlet RateView *rateView;
#property (weak, nonatomic) IBOutlet UILabel *statusLabel;
#end
CustomTableviewcell.m
#synthesize rateView,staticlbl,statusLabel,commenttxtview,Kpiidlbl;
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
commenttxtview.layer.borderWidth = 0.70f;
commenttxtview.layer.borderColor = [[UIColor blackColor] CGColor];
commenttxtview.delegate=self;
UIToolbar* doneToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
doneToolbar.barStyle = UIBarStyleBlackTranslucent;
doneToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButtonClickedDismissKeyboard)],
nil];
[doneToolbar sizeToFit];
commenttxtview.inputAccessoryView = doneToolbar;
lbl = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 0.0,90.0, 34.0)];
[lbl setText:#"Enter Text"];
[lbl setFont:[UIFont systemFontOfSize:12]];
[lbl setBackgroundColor:[UIColor clearColor]];
[lbl setTextColor:[UIColor lightGrayColor]];
commenttxtview.delegate = self;
[commenttxtview addSubview:lbl];
statusLabel.hidden=YES;
commenttxtview.hidden=YES;
// Do any additional setup after loading the view from its nib.
self.rateView.notSelectedImage = [UIImage imageNamed:#"not_selected_star#2x.png"];
self.rateView.halfSelectedImage = [UIImage imageNamed:#"half_selected_star#2x.png"];
self.rateView.fullSelectedImage = [UIImage imageNamed:#"selected_star#2x.png"];
self.rateView.rating = 0;
self.rateView.editable = YES;
self.rateView.maxRating = 5;
self.rateView.delegate = self;
Kpiidlbl.hidden=YES;
}
-(void)doneButtonClickedDismissKeyboard
{
[commenttxtview resignFirstResponder];
// commenttxtview.hidden=YES;
}
- (void)textViewDidEndEditing:(UITextView *)theTextView
{
if (![commenttxtview hasText]) {
lbl.hidden = NO;
}
}
- (void) textViewDidChange:(UITextView *)textView
{
if(![commenttxtview hasText]) {
lbl.hidden = NO;
}
else{
lbl.hidden = YES;
}
}
- (void)rateView:(RateView *)rateView ratingDidChange:(int)rating {
self.statusLabel.text = [NSString stringWithFormat:#"%d", rating];
NSLog(#"Rating value =%#",self.statusLabel.text);
StatusValue=statusLabel.text;
NSLog(#"Status Value String =%#",StatusValue);
// Hear I am getting value of rating..in StatusValue..
int status=[StatusValue intValue];
if(status<=3)
{
commenttxtview.hidden=NO;
}
else{
commenttxtview.hidden=YES;
}
}
How can I get label and textview value in viewcontroller and I want to set rate view value to rate view after reload table.
Hear in the Image i am getting five star and If I click on less then 3 star it should have to write comment.I am taking rate value in the label.How can I get both label and textvalue in view controller.Please tell me to update question if you want more data.Thanks in Advance!
So write this in your CustomTableViewCell.h
#property(nonatomic,assign)NSInteger selectedRating;
everytime when the rating is updated in the Cell, you have to change the value of this variable.
In the viewController it depends on when you want to get the value of this cell. For example in this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
CustomTableViewCell *yourCell = (CustomerTableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%lu",yourCell.selectedRating);
}
Let me know if this was helpful!
Another way without a variable is to read the NSString in the statusLabel and change the string to a NSInteger variable...
If you are using your delegate...
Then implement the delegate RateViewDelegatein the viewController. The delegate is called in the class to which it is assigned...
Try this
You have to add the #property (nonatomic, weak) NSObject<RateViewDelegate>* delegate;
to the header file of your CustomTableViewCell.h in the method
-(UITableViewCell) cellForRowAtIndexPath....
you have to assign the delegate like this
cell.delegate = self;
Now modify your cell delegate method to this
- (void)rateView:(RateView *)rateView ratingDidChange:(int)rating {
self.statusLabel.text = [NSString stringWithFormat:#"%d", rating];
NSLog(#"Rating value =%#",self.statusLabel.text);
StatusValue=statusLabel.text;
NSLog(#"Status Value String =%#",StatusValue);
// Hear I am getting value of rating..in StatusValue..
int status=[StatusValue intValue];
if(status<=3)
{
commenttxtview.hidden=NO;
}
else{
commenttxtview.hidden=YES;
}
if([self.delegate respondsToSelector:#selector(rateView:ratingDidChange:)]){
[self.delegate rateView:rateView ratingDidChange:rating];
}
}
I have a UITextField and UILabel. When user entered some text to textField and tap "Enter" on keyboard I want to save text to the label then clear textField and make it first responder again. But something is going wrong. becomeFirstResponder does not work.
Here is the code of ViewController:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.textField addTarget:self action:#selector(saveResult:)
forControlEvents:UIControlEventEditingDidEndOnExit];
}
-(void) saveResult: (id) sender {
self.label.text = self.textField.text;
self.textField.text = #"";
[self.textField becomeFirstResponder];
}
#end
Here you go, this is a working sample, the "setFrame" methods were just made up out of the blue and you can change it up or just use the delegate methods that do all of this for you, pop this into your code, load up an iphone 6+ simulator, choose to show the hardware keyboard and this will work. There's no reason to add touch event handlers to your UITextField since the delegate methods provided by Apple do all the work for you.
#interface NSHHomeViewController () <UITextFieldDelegate>
#end
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
{
UITextField * _passwordField;
UILabel * hid;
}
- (void)viewDidLoad {
[super viewDidLoad];
hid = [UILabel new];
[hid setFrame:CGRectMake(80, 200, 300, 60)];
[hid setFont:fontMagicForBoldNavigationBarNSHFont];
[hid setBackgroundColor:[UIColor babyBlue]];
[hid setTextColor:[UIColor blackBean]];
[self.view addSubview:hid];
_passwordField = [[UITextField alloc] init];
[_passwordField setSecureTextEntry:TRUE];
[_passwordField setPlaceholder:#"Password"];
[_passwordField setReturnKeyType:UIReturnKeyGo];
[_passwordField setTextAlignment:NSTextAlignmentLeft];
[_passwordField setDelegate:self];
[_passwordField setFont:fontMagicForRegularNSHFont];
[_passwordField setEnablesReturnKeyAutomatically:true];
[_passwordField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[_passwordField setFrame:CGRectMake(30, SCREEN_HEIGHT/2, SCREEN_WIDTH-60, 55)];
UIView *spacerView4 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
[_passwordField setLeftViewMode:UITextFieldViewModeAlways];
[_passwordField setLeftView:spacerView4];
[_passwordField setTextColor:[UIColor NSHBlueColor]];
[_passwordField setValue:fontMagicForRegularNSHFont forKeyPath:#"_placeholderLabel.font"];
[_passwordField setClearButtonMode:UITextFieldViewModeAlways];
[_passwordField setBackgroundColor:[UIColor colorWithWhite:1 alpha:1]];
[self.view addSubview:_passwordField];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _passwordField) {
[hid setText:_passwordField.text];
[_passwordField setText:#""];
[_passwordField resignFirstResponder];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_passwordField becomeFirstResponder];
});
}
return TRUE;
}
This is just a working example, you need to declare your delegate correctly and declare the delegate of the UITextField correctly as you see above. Then choose which return key type you want for your button on the keyboard, you also then intercept these events by using the UITextFieldDelegate's "texFieldShouldReturn", you don't have to call a timed dispatch queue, but it put this in there for the effect of posting to the label, clearing the text, resigning the keyboard, and then after 1/2 a second, the keyboard becomes first responder again.
If you don't want target no longer. Remove the target in selector method, it works fine.
-(void) saveResult: (id) sender {
self.label.text = self.textField.text;
self.textField.text = #"";
[self.textField removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit];
[self.textField becomeFirstResponder];
}
Set Delegate and Datasource of UITextField in .h file and .m file and then try.
Hope it helps.
In my app I want to programmatically add textfield below another if required on click of a button. I already had provided two textFields. if a user want to add another textfield he can do so by clicking a button. I have already written code to obtain the textfield but the problem is that it overlaps the already designed textFields. How can I do it?
Is there any way through which I can get the x and Y co-ordinates of already designed textfield so that I can place new textField relative to those co-ordinates.
This code add textField to view dynamically when every click action on button
ExampleViewController.h
#import <UIKit/UIKit.h>
#interface ExampleViewController :UIViewController<UITextFieldDelegate>
#property int positionY;
#property int fieldCount;
#property (strong,nonatomic) UIScrollView *scroll;
#end
ExampleViewController.m
#import "ExampleViewController.h"
#interface ExampleViewController ()
#end
#implementation ExampleViewController
#synthesize positionY;
#synthesize fieldCount;
#synthesize scroll;
- (void)viewDidLoad {
[super viewDidLoad];
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.backgroundColor = [UIColor whiteColor];
[self.view addSubview:scroll];
UIButton *clickToCreateTextField = [[UIButton alloc] initWithFrame:CGRectMake(40, 80, self.view.frame.size.width-80, 75)];
[clickToCreateTextField setTitle:#"Create Text Field" forState:UIControlStateNormal];
[clickToCreateTextField addTarget:self action:#selector(clickedButton) forControlEvents:UIControlEventTouchUpInside];
[clickToCreateTextField setBackgroundColor:[UIColor blackColor]];
[scroll addSubview:clickToCreateTextField];
positionY = clickToCreateTextField.center.y;
fieldCount = 0;
// Do any additional setup after loading the view.
}
-(void) clickedButton{
//add text field programmitacally
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(40, positionY, self.view.frame.size.width-80, 75)];
textField.delegate = self;
//give a tag to determine the which textField tapped
textField.tag = fieldCount;
textField.placeholder = [NSString stringWithFormat:#"Your dynamically created textField: %d", fieldCount ];
[scroll addSubview:textField];
//check if the textFields bigger than view size set scroll size and offset
if (positionY>= self.view.frame.size.height) {
scroll.contentOffset = CGPointMake(0, positionY);
scroll.contentSize = CGSizeMake(scroll.frame.size.width, scroll.frame.size.height+positionY);
}
fieldCount++;
//increase the position with a blank place
positionY = positionY+textField.frame.size.height+20;
}
#pragma mark TextField Delegate Methods
-(void) textFieldDidBeginEditing:(UITextField *)textField{
//Do what ever you want
}
-(void) textFieldDidEndEditing:(UITextField *)textField{
[textField resignFirstResponder];
//do anything
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
You can do any additional changes on this code.
I think this example explain your answer.
Hope it helps.
Use a counter and calculate y like this counter*texfield.frame.size.height.
I have a UITextfield and when the text field is equal to "test", I want to clear out the text field and change the font color to green. The code below almost accomplishes it.
- (void)editingDidBegin:(id)sender {
UITextField *txtfld = (UITextField*)sender;
if ([txtfld.text isEqualToString:(#"test")]) {
txtfld.text = #" ";
[txtfld setFont:regularFont];
[txtfld setTextColor:[UIColor greenColor]];
}
}
The only problem is I want to change:
txtfld.text = #" ";
to:
txtfld.text = #"";
When I do that, the font color remains the original black color. If I leave it as #" " then the font changes to green. Any ideas? Thanks in advance.
Scenario:
(1) user enters nothing in the text field and clicks the submit button - works
(2) the submit button updates the text field with the word "test" and makes it red - works (3) when the user goes back to the text field I want the word test deleted and when the user types for all the text to green. - Doesn't work
Note: I placed my code in the event "Editing Did Begin" as i figured when the user goes to update the field it should clear the text and allow them to type in green font color.
It is interesting that when you set text to #"" or nil, and also set textColor in UIControlEventEditingDidBegin event handler, the textColor is not set what so ever. So the silver lining is to set textColor at a later time, also see the comments in code:
- (IBAction)textEditingDidBegin:(id)sender
{
UITextField *field = (UITextField *)sender;
if ([field.text isEqualToString:#"test"]) {
[field setText:#""];
[self performSelector:#selector(setColor:) withObject:sender afterDelay:0.01];
[field setFont:[UIFont fontWithName:#"Georgia" size:15]];
}
}
- (void)setColor:(id)sender
{
// See this line of code closely, do NOT use sender, use textField property in your view controller class
[self.textField setTextColor:[UIColor greenColor]];
}
I just tested your code. It should work. You are reverting the color elsewhere.
You can test it in a new single view project with this code:
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
#property (nonatomic, weak) IBOutlet UITextField *textField;
-(IBAction)checkColor:(UIButton *)sender;
#end
#implementation ViewController
-(void)checkColor:(UIButton *)sender {
_textField.text = #"check color";
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
if ([textField.text isEqualToString:#"test"]) {
textField.text = #"";
textField.textColor = [UIColor greenColor];
}
else {
textField.textColor = [UIColor darkTextColor];
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
#end
I have been trying to do this simple thing : adding an action to a simple custom view. I have looked over the internet and found two "easy" solution :
UITapGestureRecognizer
UIButton
I want to do this programmatically and I just need to handle the tap.
Here is my code so far, I've tried both solutions separately and together and it doesn't work !
.m
#import "AreaView.h"
#implementation AreaView
#define GREY 27.0/255.0
#define PINK_R 252.0/255.0
#define PINK_G 47.0/255.0
#define PINK_B 99.0/255.0
- (id) initWithFrame:(CGRect)frame imageName:(NSString *)imageName areaName:(NSString *)areaName minimumSpending:(int)minimumSpending andCapacity:(int)capacity
{
self = [self initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithRed:GREY green:GREY blue:GREY alpha:1];
self.userInteractionEnabled=YES;
//Init variables
_areaName=areaName;
_capacity=capacity;
_minimumSpending=minimumSpending;
//Image view
_logoImageView = [[UIImageView alloc]initWithFrame:CGRectMake(5, 4, 66, 50)];
//_logoImageView.image = [UIImage imageNamed:imageName];
_logoImageView.backgroundColor = [UIColor grayColor];
//Label
_areaNameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 54, 76, 18)];
_areaNameLabel.textAlignment = NSTextAlignmentCenter;
_areaNameLabel.textColor = [UIColor whiteColor];
_areaNameLabel.font = [UIFont systemFontOfSize:12.0];
_areaNameLabel.text = areaName;
//button
_button = [[UIButton alloc]initWithFrame:self.bounds];
_button.userInteractionEnabled=YES;
_button.backgroundColor=[UIColor yellowColor];
[_button addTarget:self action:#selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];
//tap gesture racognizer
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[self addGestureRecognizer:tapRecognizer];
[self addSubview:_logoImageView];
[self addSubview:_areaNameLabel];
[self addSubview:_button];
}
return self;
}
-(void)handleTap:(UIButton *)button
{
NSLog(#"tapped!");
}
-(void)tapped:(UITapGestureRecognizer *)recognizer
{
NSLog(#"tapped!");
}
#end
.h
#import <UIKit/UIKit.h>
#interface AreaView : UIView <UIGestureRecognizerDelegate>
#property (nonatomic) UIImageView *logoImageView;
#property (nonatomic) UILabel *areaNameLabel;
#property (nonatomic) NSString *areaName;
#property (nonatomic) int minimumSpending;
#property (nonatomic) int capacity;
- (id) initWithFrame:(CGRect)frame imageName:(NSString *)imageName areaName:(NSString *)areaName minimumSpending:(int)minimumSpending andCapacity:(int)capacity;
#property (nonatomic, strong) UIButton *button;
#end
Thanks for your help!
EDIT
The problem is that both handleTap and tapped are never fired even if I comment the button solution or the tap gesture one to test them separately. For the button implementation, I can see it on my interface but clicking on it does nothing.
My UIView is then added programmatically several times (for several views) in a UIScrollview.
EDIT 2
The problem is more complicate than that. The custom view is inside a scrollview which is inside another different custom view whose main function is to rewrite hittest, so that touches on this view are held by the scrollview. (Here is the purpose of all that).
It seems that as long as hittest is involved, it doesn't work.
Implement this delegate method, which will help you.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
id touchedView = gestureRecognizer.view;
if ([touchedView isKindOfClass:[UIButton class]])
{
return NO; //It won't invoke gesture method, But it'll fire button method.
}
return YES;
}
I'm not sure why your UIButton and UITapGestureRecognizer selectors aren't firing. However another option to handle taps on a view is to simply override the touchesEnded:withEvent method:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
//handle a tap
}
That way, you won't have to create a UIButton or a UITapGestureRecognizer object at all.