I'm developing application.
I make a custom UITableViewCell.
But I can't get custom tableviewcell's contents.
For example, here's my custom UITableViewCell's image.
TextEditorCell.h
...
#property (weak, nonatomic) IBOutlet UITextField *textField;
...
AddNewObject.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
_textEditor = [tableView dequeueReusableCellWithIdentifier:#"Text"];
_datePicker = [tableView dequeueReusableCellWithIdentifier:#"Date"];
SwitchCell *_switch = [tableView dequeueReusableCellWithIdentifier:#"Switch"];
// Configure the cell...
if (indexPath.section == 0) {
return _textEditor;
}else if (indexPath.section == 1){
return _datePicker;
}else{
_switch.titleLabel.text = #"Main Countdown";
return _switch;
}
return nil;
}
...
- (IBAction)Done:(id)sender
{
NSLog(#"Text:%#",_textEditor.textField.text);
}
Log
2013-12-27 23:47:58.498 Application[10039:80b] Text:(null)
I wrote a sentence.
But log is null.
why?
Cell is a View and it shouldn't store any data. I assume that your IBAction is inside your custom cell class. So if you want to pass the parameters in there (even on the same class) you have to unfortunately set your property to strong:
#property (strong, nonatomic) IBOutlet UITextField *textField;
I solved my own question.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
TextEditorCell *cell = (TextEditorCell*)[self.tableView cellForRowAtIndexPath:indexPath];
NSString *text = cell.textField.text;
NSLog(#"Text:%#",text);
I thank every answerer!!!
Related
Im using a tableview with custom cells.
Following is my cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// AssigneeCell *cell = (AssigneeCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
static NSString *cellIdentifier = #"Cell";
AssigneeCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
[tableView registerNib:[UINib nibWithNibName:#"AssigneewiseView" bundle:nil] forCellReuseIdentifier:#"Cell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
NSLog(#"call");
}
cell.unitNameVal = unitNameResult[indexPath.row];
cell.domainNameVal = domainNameResult[indexPath.row];
cell.compliedVal = compliedResult[indexPath.row];
cell.delayedVal = delayedResult[indexPath.row];
cell.inProgressVal = inProgressResult[indexPath.row];
cell.notCompliedVal = notCompliedResult[indexPath.row];
cell.totalVal = totalValResult[indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [compliedResult count];
}
numberOfRowsInSection is called and hence my tableview contains multiple views depending upon the count of compliedResult.
But the problem is that, the values for uilabels present in my custom cell is not being assigned and hence its not visible. Why is that so?
First suggestion, create your model:
#interface Result: NSObject
#property (nonatomic) NSString* unitName;
#property (nonatomic) NSString* domainName;
#property (nonatomic) NSString* complied;
#property (nonatomic) NSString* delayed;
#property (nonatomic) NSString* inProgress;
#property (nonatomic) NSString* notComplied;
#property (nonatomic) NSString* totalVal;
#end
In this way, your viewController will have an array of Result object.
Inside your custom cell, define:
#implementation AssigneeCell
+ (NSString*)cellIdentifier {
return #"Cell";
}
- (void)setupWithResult:(Result*)result {
self.unitNameVal.text = result.unitName;
self.domainNameVal.text = result.domainName;
self.compliedVal.text = result.complied;
self.delayedVal.text = result.delayed;
self.inProgressVal.text = result.inProgress;
self.notCompliedVal.text = result.notComplied;
self.totalVal.text = result.totalVal;
}
#end
Finally in your view controller:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView registerNib:[UINib nibWithNibName:#"AssigneewiseView" bundle:nil] forCellReuseIdentifier:[AssigneeCell cellIdentifier]];
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString* cellIdentifier = [AssigneeCell cellIdentifier];
AssigneeCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
[cell setupWithResult: results[indexPath.row]];
return cell;
}
This ensure clean code and code reuse.
Since unitNameVal, domainNameVal, etc. are labels, make sure you are setting their text property. What you are doing right now is setting the labels themselves as different objects.
Assuming your arrays are arrays of strings, this should do the trick for you:
cell.unitNameVal.text = unitNameResult[indexPath.row];
cell.domainNameVal.text = domainNameResult[indexPath.row];
...
I have a UITableViewController which consists of a TableView and a UILabel. UITableViewSource feeds data to the TableView through custom UITableViewCell. UITableViewCell consists of a Stepper which can add items and the Label holds that value.
I want to update the UILabel in UIViewController when the user taps on the Stepper and i cannot seem to get that to work...
Any help/tips are greatly appreciated! Here is sample code from my test project, there is a bunch of unused code but this is just a test so i let it be there.
Thanks,
The Code is
My Custom Cell Class is "StepperDetailsCell".
#interface StepperDetailsCell : UITableViewCell
#property (nonatomic,weak) id <StepperDetailsCellDelegate> delegate;
#property (strong, nonatomic) IBOutlet UIImageView *imagegroceries;
#property (strong, nonatomic) IBOutlet UIStepper *objstepper;
#property (strong,nonatomic) IBOutlet UILabel *lblsteppervalue;
-(IBAction)stepperclicked:(UIStepper*)sender;
#end
and My table view class is named as "SecondViewController"
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Cell";
cell = (StepperDetailsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
cell = (StepperDetailsCell *)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
[cell.imagegroceries setImage:[UIImage imageNamed:[[self.didSelectedImages sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]objectAtIndex:indexPath.row]]];
[cell.objstepper addTarget:self action:#selector(stepperValuechanges:) forControlEvents:UIControlEventValueChanged];
cell.lblsteppervalue.text = [self.quantityArr objectAtIndex:indexPath.row];
return cell;
}
pragma mark - Stepper Action Method
-(void)stepperValuechanges:(UIStepper *)sender{
CGPoint stepperPosition = [sender convertPoint:CGPointZero toView:self.tableView];
indexPath1 = [self.tableView indexPathForRowAtPoint:stepperPosition];
if (indexPath1 != nil )
{
float val = sender.value;
valueInt = (int)val;
[self.quantityArr replaceObjectAtIndex:indexPath1.row withObject:[NSString stringWithFormat:#"%i",valueInt]];
NSLog(#"%#",self.quantityMDict);
}
[self.tableView reloadData];
}
Here, Everything is working properly,but whenever new cell is loading from bottom of tableview, then that time new cell stepper act as disappeared cell stepper.
Finally After 3 days I solved my problem.
Just set the value for UIStepper before firing the action of the UIStepper Object to the corresponding Controller Object like the following way..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"Cell";
cell = (StepperDetailsCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil){
cell = (StepperDetailsCell *)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
[cell.imagegroceries setImage:[UIImage imageNamed:[[self.didSelectedImages sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]objectAtIndex:indexPath.row]]];
// I just set the previous value(this value, I am taken from the array named "quantityArr") to corresponding stepper, before firing the action to the controller object from the stepper object. That's it..
[cell.objstepper setValue:[[self.quantityArr objectAtIndex:indexPath.row] doubleValue]];
[cell.objstepper addTarget:self action:#selector(stepperValuechanges:) forControlEvents:UIControlEventValueChanged];
cell.lblsteppervalue.text = [self.quantityArr objectAtIndex:indexPath.row];
return cell;
}
I have a UITableView which contains the names of all countries.
The user can delete or edit the name of country anytime by taping on the cell.
My UITableView cell initially looks like this:
Now when user taps on it I am changing it like this:
I think I am following a very lame approach.Here is what I did:
Declared globally buttons to add:
UIButton *btnDeleteWithImage,*btnDeleteWithText,*btnEditWithImage,*btnEditWihtText; //buttons
And a NSMutableArray to keep track of indexPath.row
Now in my didSelectMethod I am doing this:
//To change the background
UIView *selectionBackground = [[UIView alloc] init];
selectionBackground.backgroundColor = [UIColor customColor];
cell.selectedBackgroundView = selectionBackground;
// to check which cell is pressed
if([indexPathCollection containsObject:index])
{
[btnDeleteWithImage removeFromSuperview];
[btnDeleteWithText removeFromSuperview];
[btnEditWihtText removeFromSuperview];
[btnEditWithImage removeFromSuperview];
[indexPathCollection removeObject:index];
[cell addSubview:btnDeleteWithImage];
[cell addSubview:btnDeleteWithText];
[cell addSubview:btnEditWithImage];
[cell addSubview:btnEditWihtText];
[indexPathCollection addObject:index];
}
else
{
[cell addSubview:btnDeleteWithImage];
[cell addSubview:btnDeleteWithText];
[cell addSubview:btnEditWithImage];
[cell addSubview:btnEditWihtText];
[indexPathCollection addObject:index];
}
But this is not working good.When I scroll table edit and delete button randomly occurs.
Did someone has better Idea how can achieve this in a very efficient way.
You can achieve this by creating a custom cell with your properties
CustomCell.h
#interface CustomCell : UITableViewCell
#property (nonatomic, strong) UIButton *btnDeleteWithImage;
#property (nonatomic, strong) UIButton *btnDeleteWithText;
#property (nonatomic, strong) UIButton *btnEditWithImage;
#property (nonatomic, strong) UIButton *btnEditWithText;
#end
initialize them in cell's init method keeping them hidden at first or you can do
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *customCellIdentifier = #"customCellIdentifier";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:customCellIdentifier];
if (!cell) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:customCellIdentifier];
// or you can initialize and add them to the cell here
}
//here you can modify them accordingly
return cell;
}
then the delegate method can be
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
CustomCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell.btnDeleteWithImage setHidden:NO];
[cell.btnEditWithImage setHidden:NO];
}
the simplest way is that do not reuse the cell . & register your custom cell with same indentifire .
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
customCell* cell = [[customCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:#"indentifire"] ;
// manage your plooting here ..
return cell;
}
hope it works for you.
I would like to hide an expanded tableviews label, when the cell is expanded and hide a button when it is collapsed. I have my cell implementation in another class, with the property of the label and the button in the header. The problem is that when I call these cell methods in the ExpandedViewController, the code goes into the method, but it won't change the properties behaviour. Could you possibly help me with this issue?
Thank you
ExpandedCell.h
#property (nonatomic, retain) IBOutlet UILabel *lblTitle;
#property (strong, nonatomic) IBOutlet UIButton *setTime;
ExpandedCell.m
(void)setIfHidden:(BOOL)showIfHidden
{
if (showIfHidden)
{
[self.lblTitle setHidden:YES];
[self.setTime setHidden:NO];
}
else
{
[self.lblTitle setHidden:NO];
[self.setTime setHidden:YES];
}
}
ExpandedViewController.m
import ExpandedCell.h
.
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath isEqual:self.expandedIndexPath])
{
return CELL_HEIGHT_EXPANDED;
}
else
{
return CELL_HEIGHT_COLLAPSED;
}
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.expandedIndexPath = ([self.expandedIndexPath isEqual:indexPath]) ? nil : indexPath;
ExpandedCell *hideCell = [[ExpandedCell alloc] init];
showIfHidden = YES;
[hideCell setIfHidden:showIfHidden];
[tableView beginUpdates];
[tableView endUpdates];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Your properties are labelled as IBOutlets. You create a new instance of the cell with [[ExpandedCell alloc] init].
You have a few issues:
By calling alloc init the IBOutlets won't exist because the instance isn't unarchived from a NIB file.
Once you create hideCell, you call a method on it and then it gets destroyed (because nothing retains it).
You shouldn't be creating a new cell, you should be accessing and updating the existing one, so you should be using:
ExpandedCell *hideCell = [tableView cellForRowAtIndexPath:indexPath];
I have created a subclass of UITableViewCell and I called it DCCustomCell. This is the DCCustomCell.h file.
#import <UIKit/UIKit.h>
#interface DCCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UILabel *date;
#property (weak, nonatomic) IBOutlet UILabel *price;
#end
All the proprieties are correcty connected with elements in my iPhone.storyboard file.
I also selected the tableViewCell in iPhone.storyboard and i setted my cell's identifier to "CustomCell" and the class to DCCustomCell.
This is the UITableViewController's viewDidLoad method:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
// Do any additional setup after loading the view, typically from a nib.
}
and this is the tableView:cellForRowAtIndexPath: method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"CustomCell";
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
NSLog(#"%#" ,cell);
cell.imageView.image = [UIImage imageNamed:#"info_button.png"];
cell.title.text = #"Hello!";
cell.date.text = #"21/12/2013";
cell.price.text = #"€15.00";
return cell;
}
The problem is that the imageView is correctly setted, but all the labels are blank. If I change the imageView property name to, for example, eventImageView, the image will not be setted.
This is the result:
I can't figure out how I can solve this problem.
EDIT: if I remove
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
from viewDidLoad all seems to work. why?
As you noticed it works when you remove
[self.tableView registerClass:[DCCustomCell class] forCellReuseIdentifier:#"CustomCell"];
You only have to do this if you use dequeueReusableCellWithIdentifier:indexPath: AND have not already set the custom class in the identity inspector for that cell. If you use registerClass: forCellReuseIdentifier the cell will be initialized with initWithStyle:reuseIdentifier: instead of initWithCoder: thus screwing up your connections you made in the storyboard.
Have you bind the Controls to IBOutlet ?
You can try setting DCCustomCell to UITableviewCell's class directly in Storyboard.
And than you need to set outlets with controls in cell
Try:
if (cell == null) {
//create and initialize cell
}
after
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
You first check your outlets properly that all the labels are connected & write this also :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"CustomCell";
DCCustomCell *cell = (DCCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DCCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"%#" ,cell);
cell.imageView.image = [UIImage imageNamed:#"info_button.png"];
cell.title.text = #"Hello!";
cell.date.text = #"21/12/2013";
cell.price.text = #"€15.00";
return cell;
}