I have a UITextField in My CustomCell of UITableview and i am using this UITableview as Subview of Mainview.There is another UITableview Which is also on my MainView but i am using this UITableview as Subclass of my MainView.Below image will also be hlepfull to Understand my problem.
As image show that above UITableview is my SubClass UITableviw and Below one Which is single row UITableview with CustomCell having UITextField. Now i want that when i Click on any Cell of SubClass UITableview my UITextField Text is Clear which i have in CustomCell of UITableview.
Note:- To Make my question more easir i have some code which works for me when i have UITextfield Simply on my MainView (not in CustomCell of UITableview).here is my Code.
In Mainview.h file
#import <UIKit/UIKit.h>
#import "Inputtableview.h"
#interface testingViewController : UIViewController<UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource> {
IBOutlet UITextField *txtfinput;
Inputtableview *inputview;
IBOutlet UITableView *inputtbl;
}
#property (nonatomic, retain) UITextField *txtfinput;
#end
And then in ViewDidload of Mainview.m file
- (void)viewDidLoad {
if (inputview == nil) {
inputview = [[Inputtableview alloc] init];
}
[inputtbl setDataSource:inputview];
[inputtbl setDelegate:inputview];
inputview.view = inputview.tableView;
inputview.myAccessToMaintxtf = txtfinput;
[super viewDidLoad];
}
Now in my Subclass of UITableview.h file
#import <UIKit/UIKit.h>
#interface Inputtableview : UITableViewController<UITableViewDelegate,UITableViewDataSource> {
}
#property (nonatomic, assign) UITextField *myAccessToMaintxtf;
#end
And Finally in My SubClass UITableview.m file
#implementation Inputtableview
#synthesize myAccessToMaintxtf;
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
myAccessToMaintxtf.text=#"";
}
As i mention Earliar the Above Code works Fine when I have TextField in my MainView,But Did't know How to fix it When i Want to Clear the text of UITextField in CustomCell of UITableview.Any help Will be Appriated.Thanx in Advance.
Ok, I can't see how you are connecting "myAccessToMaintxtf"to the textfield in your CustomCell. What I use for getting subviews from my custom cells are "tags". A tag can be used like an identifier for your subviews. So, if you are using a xib you can set the tag in the settings tab of your textfield, and if you are creating the textfield by code you can set the tag like:
myAccessToMaintxtf.tag = 11; //11 is and example number, use the number that you want
Then when you want to access to your textfield use:
theTextFieldToClear = (UITextField*)[theCellWithTheTextFieldToClear viewWithTag:11];
You can find more information about tags in the UIView Class Reference:
http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html
Good Luck
EDIT 2:
If you are using two tables, and you want to clear a textfield in one table, selecting the other one, i think that you need something to make the link between the indexPath selected in one table and the indexPath for the cell with the textfield. If you are using something like:
table 1, indexpath:0,0 for celcius;
table 1, indexpath:0,1 for farenheit;
table 1, indexpath:0,2 for kelvin;
and
table 2, indexpath:0,0 for celcius;
table 2, indexpath:0,1 for farenheit;
table 2, indexpath:0,2 for kelvin;
You just can use the same indexPath to get the cell with the textfield FROM THE OTHER TABLEVIEW (Inputtableview) like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cellWithTheFieldToClear = [yourInputTableView cellForRowAtIndexPath:indexPath];
theTextFieldToClear = (UITextField*)[theCellWithTheTextFieldToClear viewWithTag:2];
theTextFieldToClear.text = #"";
}
Did you add your myAccessToMaintxtf as subview of the UITableViewCell in dataSource cellForRowAtIndexPath? If you did, you still have to reload the cell using [tableView reloadCellAtIndexPath:...];
Or another suggestion is to subclass the UITableViewCell, and add an Outlet property, connect the outlet to the TextField. Then you can do something like selectedCell.textField.text = #""; in you didSelectRowAtIndexPath.
Related
I created master details template project in xcode 4.6 and I added custom cell with 2 textfields. I also created new class which is subclass of UITableViewCell and inside this class I created outlets for text fields. When user types something NSMutableArray is updated and this works fine. Now I am wondering how to pass this array back to MasterViewController (UITableViewController) so that I can use this data to show calculations.
I tried using tutorials for delegates between UIViewControllers but I keep getting errors. Any help is appreciated.
You shouldn't keep data inside the UITableViewCell, as it breaks the MVC.
You need to get a reference of the UITextField on your cell. This is how I do in a login form:
I have a custom cell subclass called TextFieldCell, it has an outlet called textField, I want that my UITableViewController have references to these UITextFields.
First I open my storyboard, set the cell class to TextFieldCell and than connect the UITextField to cell textField outlet. Than I add this to the tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
(…)
if (indexPath.row == 0) {
// Sets the textField of the first cell as the loginTextField.
self.loginTextField = tCell.textField;
} else {
// Sets the textField of the second cell as the passwordTextField.
self.passwordTextField = tCell.textField;
}
tCell.textField.delegate = self;
(…)
}
Now I can access the value of my loginTextField and my passwordTextField. I do that on the tableView:cellForRowAtIndexPath: because that's when I'm creating the cell to add to the table view.
In your case you need to create Protocol:
I just Give Basic Idea for how to Create Protocol
Also Read This Question
#DetailViewController.h
#import <UIKit/UIKit.h>
#protocol MasterDelegate <NSObject>
-(void) getButtonTitile:(NSString *)btnTitle;
#end
#interface DetailViewController : MasterViewController
#property (nonatomic, assign) id<MasterDelegate> customDelegate;
#DetailViewController.m
if([self.customDelegate respondsToSelector:#selector(getButtonTitile:)])
{
[self.customDelegate getButtonTitile:button.currentTitle];
}
#MasterViewController.m
create obj of DetailViewController
DetailViewController *obj = [[DetailViewController alloc] init];
obj.customDelegate = self;
[self.navigationController pushViewController:reportTypeVC animated:YES];
and add delegate method in MasterViewController.m for get button title.
#pragma mark -
#pragma mark - Custom Delegate Method
-(void) getButtonTitile:(NSString *)btnTitle;
{
NSLog(#"%#", btnTitle);
}
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 am trying to display a list on my first view so added this in the first.h :
#import <UIKit/UIKit.h>
#interface argospineFirstViewController : UIViewController
<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *Journals;
IBOutlet UITableView *myTableView;
}
#property (nonatomic,retain) NSMutableArray *Journals;
#property (nonatomic, retain) UITableView *myTableView;
#end
and then i added this on my first.m :
#implementation argospineFirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Journals=[NSMutableArray arrayWithObjects:#"journal1",#"journal2",nil];
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier];
}
cell.text=[Journals objectAtIndex:indexPath.row];
return cell;
}
I am newbie so i don't really know what kind of connections i have got to make, i am also using a storyboard with a tableview dropped on the first view.
is there something i have to add to the delegate?
Any help?
Thank you for your time
Right click on the tableView in the storyboard. You will see "delegate" and "dataSource" under Outlets. Drag the bubble on the right of those to the view controller icon at the bottom of the view. This will make your viewcontroller the delegate and datasource for the table view if you don't want to do it programmatically.
Do not make property of your table view object.
Also,
in viewDidLoad method write:
myTableView.dataSource = self;
myTableView.delegate = self;
Tell me if it helps!
Use initWithStyle instead of initWithFrame for creating your cell.
In your storyboard, select your table view and open the Connections Inspector. Make sure that the delegate and datasource connections are linked to your argospineFirstViewController object.
in IBOutlet set delegete and datasource of the tableview to filesOwner
you use cell.text for show the data i think its not work in tableview just try this line:-
cell.textlabel.text=[yourArrayname objectatindex:index.row];
no need to connect delegate you already define in protocol.
I have a problem with Custom cell on story board. I need to access labels from the method called
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
How can i define it in my code? When I used IBOutlet Then It may caused the error.
So how could I access the label like
cell.textlable.text ??
Thanks alot.
I would subclass UITableViewCell. Inside the subclass create the IBOutlets and then you can access them in a regular way and set them up inside interface builder. Just be sure and set your prototype cell to be of that class. then the outlets will show up and you can access them with dot-syntax like you wanted.
An example would be:
#interface CustomCell : UITableViewCell
{
}
#property (nonatomic, retain) IBOutlet UILabel* customLabel;
#end
and the implementation is just as simple
#import CustomCell.h
#implementation CustomCell
#synthesize customLabel;
#end
It is that simple,
Then in your method you would do something like this:
CustonmCell* cell = [tableView dequeueReusableCellWithIdentifier:#"customCell"];
cell.customLabel = //whatever
//or
UILabel* mylabel = cell.customLabel;
You can add as many outlets as you would like and access them in a similar manner.
One common solution is to give each label a tag in the storyboard, and then find the label using viewWithTag: to find it in your code, like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = blah blah blah ...
...
UILabel *myLabel = [cell viewWithTag:1];
UILabel *anotherLabel = [cell viewWithTag:2];
// etc.
}
For custom cell in storyboard, use cellWillDisplay method instead of cellForRow to access cell variables.
Step 1. Create a custom MyTableViewCell:UITableViewCell class. Place the IBOutlet variables in this class.
Step 2. On Xcode IB, select the cell, change its class to MyTableViewCell. Then link the IBOutlets.
Step 3. In cellWillDisplayAtIndexPath, access the IBOutlet variables cell.myTextLabel as usual.
EDIT: Correction, if you're using Dynamic prototype, then cellForRowAtIndexPath will work. If you're using static cell then use cellWillDisplayAtIndexPath. If you're using static cell, then the steps above are not applicable, as you will be defining your IBOutlets at UITableView's view controller. Sorry for the confusion.
Just an edit to Robs answer. Took me a while as it came up with an error in xcode 4. Changed it to this:
UILabel *myLabel = (UILabel *)[cell.contentView viewWithTag:1];
I am just curious. In IB, we can put a tableviewcontroller. However, as far as I know, we always subclass that tableview controller right? That way we can implement delegate, etc.
However, it seems that for some "default" behavior, IPhone intended tableviewcontroller to be used as is. Otherwise, why would IB let us put tableViewController like that?
Are there any sample code where people use tableViewController without subclassing?
Where does they implement things like what cells to draw, etc. then?
I guess the right answer of the question is that it's simply ridiculous to use a UITableViewController without sub classing. No body is doing it. Please correct me if I am wrong. I am just curious.
Whether you use a subclass of UITableViewController or UIViewController you need to set the data your table is going to display, otherwise, what's the point of a blank table? To achieve that you have to subclass and implement some methods. It's also a good idea to keep the delegate and the datasource in the same controller, unless the complexity really asks for different classes.
That being said, I always create my own table controllers as a subclass of UIViewController and implement the table controllers methods myself, because it gives you more flexibility. Matt Gallagher has several posts on how and why. See UITableView construction, drawing and management (revisited).
If you want to give it a try, create a subclass of UIViewController with a XIB and add the following sample code:
// interface
#import <UIKit/UIKit.h>
#interface SettingsVC : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#property (nonatomic, retain) NSMutableArray *array;
#end
// implementation
#synthesize tableView = _tableView;
#synthesize array = _array;
# pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.array count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int row = [indexPath row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [self.array objectAtIndex:row];
return cell;
}
Then add a UITableView object to the XIB, link the tableView of the controller to the UITableView object, and link the delegate and datasource of the UITableView to the controller.
No, this is not necessary to inherit your class with tableViewController. You can use table view by simply
putting TableViewController in xib.
and setting its delegate and datasourse to file's owner you can draw the table cells.
I don't think you can use a UITableViewController as is, it's like using a UIViewController without subclassing it : you can't set any inner mechanics.
But you can have a UITableView without using a UITableViewController.
Sure you can use UITableViewController without subclassing it.
Samplecode is very easy and straight forward.
For example like this:
- (IBAction)selectSomeOption:(id)sender {
UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
tableViewController.tableView.dataSource = self;
tableViewController.tableView.delegate = self;
tableViewController.title = "Select some option";
[self.navigationController pushViewController:tableViewController animated:YES];
}
and the UITableViewDatasource and Delegate methods go into the same class.
Sure, if you like pain you could create a UIViewController in code and add a tableView on your own.
Or create a subclass for such an easy task.
The use of a non subclassed UITableViewController is sometimes convenient.