I am using custom delegation with my UITextField in a custom UITableViewCell. Basically I have UITextFields on my UITableView, and in Edit mode, I want to be able to edit the content inside the UITextField.
My issue is that when I go into Edit mode and try to type something in the text field, I am only able to type one character and it doubles. In this example, I tried to type "p" and it only lets me type "p" and it changes to "pp".
Here's my code. As an FYI I am pretty new to iOS/programming/custom delegation/custom UITableViewCells.
UITableViewCell subclass .h:
#protocol MenuTableViewCellDelegate <NSObject>
- (void)updatedFoodItem:(NSString *)foodItem fromCell:(id)sender;
#end
#interface MenuTableViewCell : UITableViewCell <UITextFieldDelegate>
#property (nonatomic, weak) id <MenuTableViewCellDelegate> delegate;
#property (weak, nonatomic) IBOutlet UITextField *foodTextField;
#property (weak, nonatomic) IBOutlet UITextField *priceTextField;
#end
UITableViewCell .m:
- (void)awakeFromNib {
self.foodTextField.delegate = self;
}
// Delegate method for tableview cell - food item text field is within cell.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
[self.delegate updatedFoodItem:string fromCell:self];
return YES;
}
In my ViewController.m:
- (void)updatedFoodItem:(NSString *)foodItem fromCell:(MenuTableViewCell *)cell
{
NSIndexPath *p = [self.menuTableView indexPathForCell:cell];
id item = self.menuItemsArray[p.row];
cell.foodTextField.text = foodItem;
}
By the way I realize that the above probably isn't updating my data yet, I haven't figured it out yet so any advice would be great.
The problem is that you're calling your updatedFoodItem: method and then returning YES in your shouldChangeCharactersInRange: function. Essentially what's happening is:
1 - shouldChangeCharactersInRange: is called
2 - This function calls updatedFoodItem:
3 - The updatedFoodItem: function sets the cell's text field to the original text passed in
4 - The shouldChangeCharactersInRange: method returns YES, appending the same text that was just set in the updatedFoodItem: function to the cell's label
I'm not sure exactly what you're trying to do (maybe you're trying to save the food item into your self.menuItemsArray?), but you should either not set the cell's text in the updatedFoodItem: function, or you should return NO in your shouldChangeCharactersInRange: function.
Related
I have toggle buttons in my tableview cells and I click them on for some cells but when I scroll down, those same buttons are selected for the bottom cells as well even though I didn't select them yet. I know this is happening because of the tableview reusing cells...is there any way I can fix this?
The cells are dynamic, not static.
what the tableview looks like
** EDIT: Also, lemme know if my logic seems alright: I tried creating a mutable array in my viewcontroller class and then setting all it's values to #"0". Then, in my tableviewcell's class, I set the value in the array to #"1" at the index of the current cell if I select the button, so then back in my viewcontroller class, I can tell if I have already selected a button at that cell or not. The only flaw is that I can't access the array in my tableviewcell's class, it is coming out at null...i guess that it because of the mvc pattern in objective c. Any advice?
EDIT
I am still unable to resolve my issue. Can someone please help me? I have been stuck on it for a while now!
I am trying to create a tableview where the cells have a check and cross button and when I click the check button, it should turn green, but the same button in other cells should remain gray, however, when I scroll down, some cells that I didn't select buttons in still turn green...because of cell recycling.
I am using delegates and protocols right now but it isn't working; perhaps I am using it wrong?
I am setting yesChecked value in IBaction functions in my cell class, and in my viewcontroller class, I am using that yesChecked value to see what color to give to the button based on whether it says "yes" or "no".
Kindly help! Thanks!
#protocol DetailsTableViewCellDelegate <NSObject>
- (void) customCell:(DetailsTableViewCell *)cell yesBtnPressed:(bool)yes;
#property (nonatomic, retain) NSString * yesChecked;
You'd have to select or deselect them in cellForRowAt. For example if your cell had a leftButton property and you had a model like this, you could do something like the following:
#interface Model : NSObject
#property (nonatomic, assign) BOOL selected;
#end
#protocol CustomCellDelegate <NSObject>
- (void)cellActionTapped:(UITableViewCell *)cell;
#end
#interface CustomCell : UITableViewCell
#property (nonatomic, assign) BOOL leftButtonSelected;
#property (weak, nonatomic, nullable) id<CustomCellDelegate> delegate;
#end
// ModelViewController.h
#interface ModelViewController : UIViewController<CustomCellDelegate>
#end
// ModelViewController.m
#interface ViewController () {
NSArray<Model*>* models;
}
#end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier"];
((CustomCell *)cell).delegate = self;
((CustomCell *)cell).leftButtonSelected = models[indexPath.row].selected;
return cell;
}
- (void)cellActionTapped:(UITableViewCell *)cell {
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Update data source using (maybe) indexPath.row
}
I have toggle buttons in my tableview cells and I click them on for some cells but when I scroll down, those same buttons are selected for the bottom cells as well even though I didn't select them yet. I know this is happening because of the tableview reusing cells...is there any way I can fix this?
The cells are dynamic, not static.
what the tableview looks like
** EDIT: Also, lemme know if my logic seems alright: I tried creating a mutable array in my viewcontroller class and then setting all it's values to #"0". Then, in my tableviewcell's class, I set the value in the array to #"1" at the index of the current cell if I select the button, so then back in my viewcontroller class, I can tell if I have already selected a button at that cell or not. The only flaw is that I can't access the array in my tableviewcell's class, it is coming out at null...i guess that it because of the mvc pattern in objective c. Any advice?
EDIT
I am still unable to resolve my issue. Can someone please help me? I have been stuck on it for a while now!
I am trying to create a tableview where the cells have a check and cross button and when I click the check button, it should turn green, but the same button in other cells should remain gray, however, when I scroll down, some cells that I didn't select buttons in still turn green...because of cell recycling.
I am using delegates and protocols right now but it isn't working; perhaps I am using it wrong?
I am setting yesChecked value in IBaction functions in my cell class, and in my viewcontroller class, I am using that yesChecked value to see what color to give to the button based on whether it says "yes" or "no".
Kindly help! Thanks!
#protocol DetailsTableViewCellDelegate <NSObject>
- (void) customCell:(DetailsTableViewCell *)cell yesBtnPressed:(bool)yes;
#property (nonatomic, retain) NSString * yesChecked;
You'd have to select or deselect them in cellForRowAt. For example if your cell had a leftButton property and you had a model like this, you could do something like the following:
#interface Model : NSObject
#property (nonatomic, assign) BOOL selected;
#end
#protocol CustomCellDelegate <NSObject>
- (void)cellActionTapped:(UITableViewCell *)cell;
#end
#interface CustomCell : UITableViewCell
#property (nonatomic, assign) BOOL leftButtonSelected;
#property (weak, nonatomic, nullable) id<CustomCellDelegate> delegate;
#end
// ModelViewController.h
#interface ModelViewController : UIViewController<CustomCellDelegate>
#end
// ModelViewController.m
#interface ViewController () {
NSArray<Model*>* models;
}
#end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseIdentifier"];
((CustomCell *)cell).delegate = self;
((CustomCell *)cell).leftButtonSelected = models[indexPath.row].selected;
return cell;
}
- (void)cellActionTapped:(UITableViewCell *)cell {
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Update data source using (maybe) indexPath.row
}
i'm new in Objective C . What i'm going to do is simple just to animate keyboard up when textfield is focused and shrink when it's not. I already followed some other tutorial on how to set up this step by step but it not working.The event textViewDidBeginEditing is never get called when textfeld is focus.
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *cCodeTextField;
#property (weak, nonatomic) IBOutlet UITextField *jidTextField;
- (IBAction)nextBtnTapped:(id)sender;
#end
I'm also set the delegate to the textfield but it's not working.
- (void)viewDidLoad {
[super viewDidLoad];
[self addTextFieldBorder:_jidTextField];
[self addTextFieldBorder:_cCodeTextField];
_jidTextField.delegate = self;
}
-(void) textViewDidBeginEditing:(UITextView *)textView {
NSLog(#"Enter");
}
It looks like your ViewController class is implementing methods from the wrong delegate. It is implementing UITextViewDelegate methods when it should be implementing UITextFieldDelegate methods.
Note that 'jidTextField' is of type UITextField.
Your delegate method is called 'textViewDidBeginEditing' which is a UITextViewDelegate method and takes a UITextView as a parameter.
The issue here is that your class is implementing delegate functions for UITextViewDelegate and not UITextFieldDelegate.
The correct method definition is:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
Here is a link to the documentation for the correct delegate:
https://developer.apple.com/reference/uikit/uitextfielddelegate
Hope this helps!
I'm developing an iOS-App and therefore I use a UITableViewController. Within "cellForRowAtIndexPath" I use cells with reuse identifiers:
[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle1 reuseIdentifier:textFieldIdentifier];
The problem is that some cells have a dependecy on each other, e.g. if the user enters text in one cell another cell changes its value.
So what is the best way to safe a reference to the cell that has to be changed? The problem is, that if I safe the reference within "cellForRowAtIndexPath", during the callback for "textFieldDidChange" the reference might be broken, e.g. if the cell is not visible or another cell has the adress due to the reuse identifier?!
Don't try to save references to cached cells. Update whatever you need to display in the table's data source and then call reloadData. That way, the table takes care of refreshing visible cells and dealing with the cache...so you don't need to.
I would make an protocol for the cells
Example
#protocol MyProtocol <NSobject>
- (void) changeText:(NSString)theText;
#end
#interface TableViewCell1 : UITableViewCell
#property (nonatomic, weak) id<MyProtocol> delegate;
#end
#implementation TableViewCell1
//put this in the method where you get the value of the textfield
[self.delegate chageText:#"Hello"];
#end
#interface TableViewCell2 : UITableViewCell <MyProtocol>
#end
#implementation TableViewCell2
- (void) chageText:(NSString *)text {
self.textLabel.text = text;
}
#end
I'm making an application that requires the use of multiple textFields with number pads as there first responder. I have created an image to use as a negative button that will be an addition to the number pad.
I am wondering if there is a way to check which textField the number pad is typing to.
Any help would be appreciated!
If all of your potential first responders are UITextFields, another approach would be to conform your controller class to UITextFieldDelegate protocol, and then grab a reference to the currently editing UITextView at the time it begins editing.
Conform your class in your .h:
MyController : NSObject <UITextFieldDelegate> //Might often be a UIViewController rather than an NSObject subclass...
Define a property:
#property (weak, nonatomic) UITextField *editingField;
Then synthesize in your .m:
#synthesize editingField = __editingField
Then implement:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self setEditingField:textField];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self setEditingField:nil];
}
Now, whenever you want to know which text field is your first responder:
UITextField *firstResponder = [self editingField];
If there are only a limited number of them, you can query each with [textFieldN isFirstResponder]. If you want a general purpose utility, you can look at each subview in a view and see whether it is the first responder or whether any of its subviews farther down the hierarchy are.