I have a view which contains a tableview, (i call this view the EquationView, and its controller the EquationViewController). The table view cells are custom cells with a label and a textfield, representing a variable and its value, receptively. I have been able to get my custom keyboard to apear when editing begins in the textfield.
However, I haven't been able to get the keystrokes to apear in the correct cell, do to the fact that I haven't been able figure out how to send the indexPath of the cell with textfield being edited to the custom keyboard controller class. I have included my EquationViewController.h file in my custom keyboard controller class and have been able to change the text in the tableview's textFields by manually setting the indexPath to a specified row. Here is the keyboard class definition:
#import <UIKit/UIKit.h>
#import "EquationViewController.h"
#interface CustomNumberPadViewController : UIViewController {
EquationViewController *equationViewController;
}
#property (nonatomic, retain) EquationViewController *equationViewController;
-(IBAction)buttonPressed:(id)sender;
#end
My action method looks like this (so far):
-(IBAction)buttonPressed:(id)sender{
VariableCell *cell = (VariableCell *)[equationDetailViewController.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
cell.variableValue.text = #"test";
}
This get the word "test" to appear on whichever row I set in the index path.
So what I'm wondering is, is there a way to pass/get the indexPath of the cell whose textField is being edited to the action method in my custom keyboard controller class?
Why don't you set your UIViewController as the delegate of your UITextFields and catch the textFieldDidBegin: delegate method?
Related
In my application, I have a button that pushes a custom view controller (MenuViewController) on click.
#interface MenuViewController : UITableViewController
I wasn't able to resize the tableview. I tried:
self.tableView.frame=CGRectMake(0, 0,100, 100);
self.View.frame=CGRectMake(0, 0,100, 100);
in viewDidLoad and viewWillAppear. Neither of these methods worked.
I have an idea of creating a UIView initwithframe:.. and add MenuViewController as a subview.
Is this the proper way to do it?
MenuViewController is basically a general control that will handle variable init inputs
and will display the cells according to the inputs, the problem is the frame of the table view.
I believe that if you inherit from UIViewController and expose the UITableView as a property and also on the Interface then you can resize it. When you are using UITableViewController then it will always display in full size mode.
UPDATE:
So instead of doing something like this:
#interface TasksViewController : UITableViewController
{
}
You can do something like this:
#interface TasksViewController : UIViewController<UITableViewDelegate>
{
}
#property (nonatomic,weak) IBOutlet UITableView *tableView;
Also make sure that in interface builder you have a UITableView which is hooked to the tableView property in the TasksViewController. Now in your implementation file implement the cellForRowAtIndexPath method and return the cell.
So I have looked around a quite a bit, and nothing on here seems to explain exactly the correct way of doing this. I have 7 UITextFields within a custom UITableViewCell.
My question is this: What is the correct way of managing the delegate of these UITextFields?
Since the custom cells are technically part of the "model" portion of the project, I would rather have the controller that controls the UITableView also control the text fields in the table's cells, but I can not figure out how to set the delegate for the text fields (which are created in the subclass of UITableViewCell) to this view controller.
Would it be bad practice to just make the subclass of UITableViewCell conform to UITextField delegate and manage all of that stuff in there? If so, how else should I go about doing this?
Thanks, any help would be appreciated.
You shouldn't have a problem setting the delegate of the cell's text field to be your view controller.
This is what you need to do:
1) The view controller needs to implement the UITextFieldDelegate protocol
2) Declare a property for the text field in your custom cell
#property (nonatomic, retain) IBOutlet UITextField *textField;
3) Then set the view controller as the text field's delegate in the method cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
// use this if you created your cell with IB
cell = [[[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil] objectAtIndex:0];
// otherwise use this
cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// now set the view controller as the text field delegate
cell.textField.delegate = self;
}
// configure cell...
return cell;
}
In my opinion the cell should manage the keyboard since it is the one that is holding the UITextField. You can set your cell as the UITextField delegate. In my own application, I have done this and then made my cell have it's own delegate. Any of the methods of UITextField or any new methods that should be handled by the controller can be passed along to the controller through the cells delegate.
In this way the cell can still be generic without knowing anything about what the application is actually doing.
My suggestion would be to "tag" (i.e. set the tag) of each textField with a value that encodes the section, row, and one-of-7 text views in the table, then make the UIViewController the delegate.
So you need to bound the size of these - say you will never have more than 100 rows. So you encode this as:
.tag = 1000*section + 100*row +
When you get a message you can have a method/function take the tag and decode it into section, row, tag, and do what you need to have done.
To declare your TableViewController as the delegate include <UITextFieldDelegate> at the end of your #interface in the TableViewController's .h file.
#interface MyTableViewController : UITableViewController <UITextFieldDelegate>
Then, connect the text fields by ctrl-dragging each field under the #interface. Each UITextField is connected to its respective property by an IBOutlet. Finally, in the .m file include the following function to show the delegate which field you want to return....
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[aTextField resignFirstResponder];
return YES;
}
Swift version (Based on Eyal's answer)
class MyViewController: UIViewController, ... , UITextFieldDelegate {
#IBOutlet var activeTextField: UITextField! //doesn't need to connect to the outlet of textfield in storyboard
....
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
....
var cellTextField = self.view.viewWithTag(101) as? UITextField
cellTextField!.delegate = self;
....
}
i have created custom Cell in a controller "CustomCellController". The custom Cell Contains a text Field.
I am Using that CustomCell in another controller "TableViewController"
How can i Set delegate method for the the textField present in "customCellController" in "TableViewController"
if you want the textfield text only ..you can make a new model singleton class and keep the text stored in it for retrieving..
If you want to be the delegate only..One way to do is.
Add a property to the TableViewController of UITextField
add a function such as
-(void) setTextField:(UITextField *) textField
{
self.textProperty = textfield;
self.textProperty.delegate = self;
}
then where you initialize TableViewController
call the method and pass the textfield to it.
So I thought I'd have a go at building my own simple app. Please go easy on me I'm new to all this! The idea is this. For iPad have a single view controller with a text box and a text field. Text box takes a title, and text field takes the body of a report. There's a button on the page to submit the report, which bundles the two texts into an object and adds it to a table view within the same view controller. I have set the view controller as a delegate with <UITableViewDelegate, UITableViewDataSource> in my header file. My table view works fine for adding items in the viewDidLoad method. But adding items from the text inputs via a UIButton connected to -(IBAction) addItem falls over with: Property 'tableView' not found on object of type 'ReportsViewController'
- (IBAction)addReportItem
{
int newRowIndex = [reports count];
ReportObject *item = [[ReportObject alloc] init];
item.title = #"A new title";
item.reportText = #"A new text";
[reports addObject:item];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0];
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
I understand that I'm trying to call a method within my object but I have other method calls to tableView which work fine. i.e.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [reports count];
}
I thought this was the point of delegation. I know I'm missing something, but as I say I am new to all this and have looked everywhere for an answer before posting. What do I need to do to send my IBAction message to tableView?
Do you have a tableView instance variable setup in your .h file of the view controller?
The reason you are able to access it in the delegate and data source methods is because they are passed in as part if the methods.
You will need to add the IBOUTLET tableView ivar and connect it to the tableView in your .xib.
Or perhaps your ivar for the tableView is named something else?
Good luck.
I had the same problem.
What helped was to inherit the View Controller from UITableViewController, instead of UIViewController. Not using the protocol names in angled brackets.
The TableView is then linked to the dataSource and delegate via the storyboard (resp. InterfaceBuilder).
The parent class UITableViewController has an IBOutlet tableView defined.
MyViewController.h:
#interface MyViewController : UITableViewController
G'day guys, I'm building an application that allows users to rapidly input numbers into a UITableView.
I've currently built the framework, but I'm having a bit of a hitch hooking up the view to have the keyboard load and make the text in the cell editable from a user action.
I remember there being an iOS example in the dev code somewhere, (like a year ago so it wouldn't be under NDA) where you added items in and edited them within the context of the UITableView without going to a detailed subview.
Just need a hint on how to hook up the delegates, or how to structure the code.
I have code where I create custom cells for a UITableView which have UITextField and UITextView controls on them. In the UITableViewController code I do this:
Interface
#interface MyTableViewController:
UITableViewController <UITextFieldDelegate, UITextViewDelegate> {
....
}
Implementation
-(UITableViewCell *) tableView:(UItableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath {
....
UITableViewCell * cell = ....
cell.myTextField.delegate = self;
cell.myTextField.tag = 1; //This should be unique.
return cell;
}
-(void) textFieldDidEndEditing: (UITextField * ) textField {
// Decide which text field based on it's tag and save data to the model.
}
-(void) textViewDidEndEditing: (UITextView * ) textView {
// Decide which text view based on it's tag and save data to the model.
}
You can add a UITextField or UITextView to any cell. If you have custom cells, make them a delegate for their text view, or if you compose the cells in your table view delegate, then make this the text fields' delegates.