I have a tableview called AdminOrderViewController and it has customcell called StepperProgressCell.
This customcell has a custom UIView called AYStepperView. There is a button in this UIView and I implemented a delegate on it, whenever it gets clicked and I clicked method is getting called on AdminOrderViewController.
However, I could not able to figure out how to pass clicked header cell.section to AYStepperView ??
AdminOrderViewController.m
#interface AdminOrderViewController : UIViewController <AYStepperViewDelegate>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"StepperProgressCell";
StepperProgressTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[StepperProgressTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.stepperView.delegate= self;
return cell;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
AdminHeaderFooterView *sectionHeaderView = [self.adminTableView dequeueReusableHeaderFooterViewWithIdentifier:SectionHeaderViewIdentifier];
if (sectionHeaderView == nil)
{
sectionHeaderView = [[AdminHeaderFooterView alloc] initWithReuseIdentifier:SectionHeaderViewIdentifier];
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectHeaderAction:)];
[sectionHeaderView addGestureRecognizer:tapGesture];
return sectionHeaderView;
}
-(void) selectHeaderAction :(UITapGestureRecognizer*) gestureRecognizer
{
AdminHeaderFooterView* cell = (AdminHeaderFooterView*)gestureRecognizer.view;
[self toggleSection:cell withSection: cell.section];
// how to pass clicked section to AYStepperView??
}
-(void)clicked :(NSUInteger) currentSection
{
NSLog(#"Stepper clicked %lu", currentSection);
}
StepperProgressTableViewCell.m
#implementation StepperProgressTableViewCell
#synthesize stepperView;
- (void)awakeFromNib {
[super awakeFromNib];
[self setUpViews];
}
- (void)setUpViews {
self.stepperView = [[AYStepperView alloc]initWithFrame:CGRectMake(0, 0 , [[UIScreen mainScreen] bounds].size.width, kFormStepperViewHeight) titles:#[#"Processing",#"Ready",#"Delivered", nil)]];
[self addSubview:self.stepperView];
}
AYStepperView.h
#property (nonatomic) NSUInteger currentSection;
AYStepperView.m
#protocol AYStepperViewDelegate <NSObject>
#required
- (void)clicked :(NSUInteger) currentSection;
#end
- (void)buttonPressed:(UIButton *)sender {
[stepperDelegate clicked : currentSection];
}
The cell should not need to know which row or section it is in; Your table view controller can find this easily, given a reference to the cell.
Your view controller should not set itself as the delegate of the stepper view. It should be a delegate of the cell. The cell should be the delegate of the stepper view. This is a bit more complicated but it maintains better separation of concerns and makes the whole thing cleaner.
AYStepperView.h
#protocol AYStepperViewDelegate <NSObject>
#required
- (void)clicked;
#end
AYStepperView.m
- (void)buttonPressed:(UIButton *)sender {
[stepperDelegate clicked];
}
StepperProgressTableViewCell.h
#protocol StepperProgressTableViewCellDelegate <NSObject>
#required
- stepperChanged: (StepperProgressTableViewCell) cell;
StepperProgressTableViewCell.m
-(void)awakeFromNib {
self.stepperView.delegate= self;
}
- (void)clicked {
[self.delegate stepperChanged: self];
}
AdminOrderViewController.m
#interface AdminOrderViewController : UIViewController <StepperProgressTableViewCellDelegate>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"StepperProgressCell";
StepperProgressTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[StepperProgressTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.delegate= self;
return cell;
}
-(void)stepperChanged:(StepperProgressTableViewCell)cell {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// Now do something with indexPath.section
}
in cellForRowAtIndexPath set section to stepper view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"StepperProgressCell";
StepperProgressTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[StepperProgressTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.stepperView.delegate= self;
cell.stepperView.currentSection = indexPath.section;//set section value
return cell;
}
Related
I am new to objective c in my tableview i populated the textfield dynamically in the uitableview cell its working fine but whenever the user types the values in the uitextfield the value get repeated to another cell textfield can anyone help me how to solve this error.This is my sample code and i also the added the sample screen shot below for your reference .
#import "TableViewController.h"
#import "TableViewCell.h"
#interface TableViewController ()<UITableViewDelegate>
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.mytableview.dataSource=self;
self.mytableview.delegate=self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellidentifier=#"cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier];
if (!cell) {
cell= [[TableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier];
}
return cell;
}
#end
Actually, text appears on another cell because the cell is reused when you create cell by TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier]
Add this code to your TableViewCell.m
- (void)prepareForReuse {
self.textfield.text = #"";
}
TableViewController.m
#import "TableViewController.h"
#import "TableViewCell.h"
#define numberOfRow 20;
#interface TableViewController ()<UITableViewDelegate, UITextFieldDelegate>
#property (nonatomic, strong) NSMutableArray* texts;
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
_texts = [[NSMutableArray alloc] init];
for (int i = 0; i < numberOfRow; i++) {
[_texts addObject:#""];
}
self.mytableview.dataSource=self;
self.mytableview.delegate=self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return numberOfRow;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellidentifier=#"cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier];
if (!cell) {
cell= [[TableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier];
}
cell.textField.text = _texts[indexPath.row];
cell.textField.tag = indexPath.row;
cell.textField.delegate = self;
return cell;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
_text[textField.tag] = textField.text;
}
#end
I've created a custom UITableViewCell and i need a bottom line separator for each cell then i put the separator in init method of my custom tableViewCell
This is my TableView code :
#import "Telegram_TableViewController.h"
#import "Custom_TableViewCell.h"
#interface Telegram_TableViewController ()
#end
#implementation Telegram_TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.array =[[NSMutableArray alloc] init];
for (int i=0; i<200; i++) {
[self.array addObject:[NSString stringWithFormat:#"item %i" ,i]];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.array count] ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *Identifier = #"CELL";
Custom_TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
cell = [[Custom_TableViewCell alloc] init];
UILabel *txt = [[UILabel alloc]init];
txt.text = [NSString stringWithFormat:#"Item " ] ;
cell.textLabel.text = [self.array objectAtIndex:indexPath.row];
return cell;
}
and my custom TableViewCell code :
#import "Custom_TableViewCell.h"
#implementation Custom_TableViewCell
- (void)awakeFromNib {
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(id)init
{
self = [super init];
if (self) {
UIEdgeInsets insets = self.separatorInset;
self.separatorInset = UIEdgeInsetsMake(0.0, 0.0,insets.bottom + 6.0, 0.0);
self.separatorInset = insets;
}
return self;
}
There is no error but it doesn't work. How can i fix it?
Thanks in advance.
Clean init method in Custom_TableViewCell and see if this helps.
In Telegram_TableViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *Identifier = #"CELL";
Custom_TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
cell = [[Custom_TableViewCell alloc] init];
UILabel *txt = [[UILabel alloc]init];
txt.text = [NSString stringWithFormat:#"Item " ] ;
cell.textLabel.text = [self.array objectAtIndex:indexPath.row];
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[tableView setSeparatorColor:[UIColor blackColor]];
return cell;
}
And make sure the color of the separator is different than the color of the cell itself.
Use this code in your cell,s .h file
#property (nonatomic,strong) UIView* cellSeperatorView;
and in .m file
-(UIView *)cellSeperatorView{
if (!cellSeperatorView) {
self.cellSeperatorView = [[UIView alloc] initWithFrame:CGRectZero];
[self.cellSeperatorView setBackgroundColor:[UIColor lightGrayColor]];
[self addSubview:self.cellSeperatorView];
}
return cellSeperatorView;
}
-(void)prepareForReuse{
self.cellSeperatorView = nil;
}
-(void)layoutSubviews{
[super layoutSubviews];
[self.cellSeperatorView setFrame:CGRectMake(0, 0, 500, 1)];
}
and call this method in your tableview class in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)..
UITableViewCellClass *cell = (UITableViewCellClass *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (!cell) {
cell = [[UITableViewCellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.cellSeperatorView.hidden = (indexPath.row == ([self.yourtableViewArray numberOfRowsInSection:indexPath.section]));
and in you viewdidload method add this
[self.yourtableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
i think this can help you for making separator..
You'd better register in the method viewDidLoad when you want to custom cell. [self.tableView registerClass:[Custom_TableViewCell class] forCellReuseIdentifier:Identifier];
What is cell = [[Custom_TableViewCell alloc] init];? You are not reusing the cell, but initiate every time. Just do not write this line.
The right way to overwrite the init method of tableViewCell to is rewrite - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
Now you can see the tableView correctly, but I do not understand a bottom line separator, just write what you want in the method initWithStyle.
I want to create a default static table in my sub-class of UITableViewCintroller, but data doesn't appear. I don't know where is the problem, I think that cellForRowAtIndexPath method not called.
Here is my code:
#import <UIKit/UIKit.h>
#interface S5WebTable : UITableViewController <UITableViewDelegate, UITableViewDataSource>
#end
#import "S5WebTable.h"
#interface S5WebTable ()
#property(assign,nonatomic) BOOL isLoaded;
#end
#implementation S5WebTable
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView sizeToFit];
}
-(void)viewWillAppear:(BOOL)animated{
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 7;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text =#":)";
return cell;
}
I think you have to use a distinct identifier for each cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"s%i-r%i", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
//you can customize your cell here because it will be used just for one row.
}
return cell;
}
First of all you have to give identifier to tableview cell then it will displays.
e.g.
NSString *cellIdentifier = [NSString stringWithFormat:#"%d_cell", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]];
}
return cell;
}
1.Drag TableView Controller in StoryBoard
2.Sele ct the TableView and in Right Inspector change number of Prototyes Cell(number of cells) and then Dynamic Prototypes to Static Cell
3.Customise the Cell according to your requirement
Tat's it Static TableView is created.Don't override any of tableview delegate or datasource methods
Below i added the screenshot of Right Inspector
So i created a custom cell (using the .xib file) and linked it using a custom controller class and I also didn't forget to write in the cell identifier. I also gave the same cell identifier in my table view controller prototype cell. In the custom cell controller class I just have an outlet to a text label in the .h file. Below is the code for my table view controller. When I run the app, the custom cells are not displayed but there are cells there because i can click on them (but they are just white). What am I doing wrong, why aren't the custom cells displaying?
If I use the default cells (not custom), then everything works fine. So the problem is that I'm not using my custom cells correctly somewhere.
#import "ListmaniaTableViewController.h"
#import "ListmaniaTableViewCell.h"
#interface ListmaniaTableViewController ()
#property (strong, nonatomic) NSMutableArray *tasks; //of task object
#end
#implementation ListmaniaTableViewController
- (void)viewDidLoad{
[super viewDidLoad];
task *task1 = [[task alloc] init];
task1.taskDescription = #"TASK 1";
[self.tasks addObject:task1];
task *task2 = [[task alloc] init];
task2.taskDescription = #"TASK 2";
[self.tasks addObject:task2];
task *task3 = [[task alloc] init];
task3.taskDescription = #"TASK 3";
[self.tasks addObject:task3];
}
- (NSMutableArray *)tasks{
if(!_tasks){
_tasks = [[NSMutableArray alloc] init];
}
return _tasks;
}
/*- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"Add New Item"]) {
}
}
- (void)addNewTask:(task *)newTask{
[self.tasks addObject:newTask];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.tasks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(ListmaniaTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
}
#end
But the
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
in viewDidLoad:.
The code you have in tableView:willDisplayCell:forRowAtIndexPath: method should be in tableView:cellForRowAtIndexPath: method. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
return cell;
}
I figured out the problem. I had an outlet in the custom cell that was doubly linked. I also moved the line below into viewdidload as suggested by #dasdom
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
i've a simple View that is the third level of a UINavigationController, it show an empty table from a nib, here is the code of the .m file:
#import "ThirdLevel.h"
#implementation ThirdLevel
#synthesize lista, categoria;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Categoria: %#", categoria);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return NO;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//newtableView.separatorColor = [UIColor clearColor];
static NSString *CellIdentifier = "Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
}
- (void)buttonPressed:(id)sender {
NSLog(#"premuto");
}
- (void)dealloc {
[super dealloc];
}
#end
When i run it, the device crash and the debugger say that there is a EXC_BAD_ACCESS at this line:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
i've the same code in the second level of the UINavigationController and it work fine, realy don't understand what's wrong.
Thanks for any help :)
static NSString *CellIdentifier =#"Cell";
not
static NSString *CellIdentifier = "Cell";
more over
return cell;//not found on ur code
May be you should return cell in this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//newtableView.separatorColor = [UIColor clearColor];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
Updated:
And as mentioned #AppleVijay add # when initializing CellIdentifier