I', have a UITableView with UISwitch in some cells.
I want to capture events, but it crashes when I try to add the indexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Create cell with all data
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
[switchview addTarget:self action:#selector(updateSwitchAtIndexPath) forControlEvents:UIControlEventTouchUpInside];
}
- (void)updateSwitchAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UISwitch *switchView = (UISwitch *)cell.accessoryView;
if ([switchView isOn]) {
NSLog(#"ON");
} else {
NSLog(#"OFF");
}
}
It crashes, I think because I'm not adding the indexPath parameter, but I can't get how to set it.
-[ParkingData updateSwitchAtIndexPath]: unrecognized selector sent to instance 0x7b88eb0
Thanks!
UPDATE
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Create cell with all data
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
[switchview addTarget:self action:#selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)updateSwitchAtIndexPath:(UISwitch *)switchview {
if ([switchView isOn]) {
NSLog(#"ON");
} else {
NSLog(#"OFF");
}
}
[switchview addTarget:self action:#selector(updateSwitchAtIndexPath) forControlEvents:UIControlEventTouchUpInside];
should be
[switchview addTarget:self action:#selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
you are missing just a colon. because your method has parameter.
- (void)updateSwitchAtIndexPath:(NSIndexPath *)indexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
[switchview addTarget:self action:#selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)updateSwitchAtIndexPath:(id)sender
{
// see the line BELOW
NSIndexPath *indexPath = [[(UITableView*)[sender superview] superview]indexPathForCell: (UITableViewCell*)[sender superview]];
if ([sender isOn])
NSLog(#"ON");
else
NSLog(#"OFF");
}
In the above code sender means UISwitch and if u want indexPath of cell then the marked line helps to you.
Related
I'd like to add UIGestureRecognizer to UITableViewCell.
When I call panAction: in CustomCell class, it will work.
But I'd like to call the method in ViewController class, and in this case, it will not work.
How do I fix it to work panAction:?
- (void)viewDidLoad
{
_tableView = [[UITableView alloc]initWithFrame:self.view.frame];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[CustomCell class] forCellReuseIdentifier:#"Cell"];
[self.view addSubview:_tableView];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *nibName = #"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:nibName];
if (!cell) {
cell = (CustomCell*)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nibName];
}
return cell;
}
- (void)setupGesture
{
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
CustomCell* cell = (CustomCell*)[_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[cell addGestureRecognizer:panRecognizer];
}
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint location = [sender translationInView:sender.view];
NSLog(#"%f", location);
[sender setTranslation:CGPointZero inView:sender.view];
}
In the code posted above, you don't call setupGesture. This way your cell won't pick up the gestures. Also, you should just add create and add panRecognizer to the cell in tableview:cellForRowAtIndexpath: like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *nibName = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:nibName];
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[cell addGestureRecognizer:panRecognizer];
return cell;
}
I want to swipe cell on click a button . I am succesful on swiping a cell. But i want to swipe on button which is in cell. my code is
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleCell";
SimpleCell *cell = (SimpleCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
SimpleCell *cekks=[[SimpleCell alloc]init];
cekks.scrollButton.alpha =0.0;
NSString *titleString;
UIButton *sender = [[UIButton alloc]init];
//[sender setBackgroundImage:[UIImage imageNamed:#"swipe.png"] forState:UIControlStateNormal];
sender.tag = indexPath.row;
titleString =#"Send A Gift";
UITableViewRowAction *sendAGift = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:titleString handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
// [self deleteMail:[NSArray arrayWithObject:indexPath]:YES];
}];
[sendAGift setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"swipe.png"]]];
return #[sendAGift];
}
I think your class SimpleCell should contain the UIButton, in order perform reusing correctly.
It will be simpler if you create a custom UITableViewCell that contains all the UI actions over the cell and operate them within the cell, not in the UITableView itself.
Let's see an example:
Here's the customCell.h file:
#interface customCell : UITableViewCell {
UIButton *buttonSwipe;
}
#end
Here's the customCell.h file:
#import "customCell.h"
#implementation customCell
- (instancetype) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
}
- (void) commonInit {
buttonSwipe = [UIButton... // Initialize here your button
[buttonSwipe addTarget:self action:#selector(swipeCell:) forControlEvents:UIControlEventTouchUpInside];
}
- (void) swipeCell {
// Embed here the code that makes the effect of swipe the cell.
}
This is a fast-untested workaround with some predefined code, but I think it's a working example if you want to make your cells swipe with your own code.
But if you want a faster way, I recommend you to visit Chris Wendel and his SWTableViewCell on GitHub
You can call editActionsForRowAtIndexPath: method as
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:SELECTED_ROW_INDEX inSection:0];
[self tableView:self.tableView editActionsForRowAtIndexPath:indexPath];
try the below code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
//swipe button allocation
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
btn.tag = indexPath.row;
[cell.contentView addSubview:btn];
[btn addTarget:self action:#selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text = [NSString stringWithFormat:#"%lu",indexPath.row];
return cell;
}
-(void)buttonTouched:(id)sender{
UIButton *btn = (UIButton *)sender;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:btn.tag inSection:0];
[self tableView:self.tableView editActionsForRowAtIndexPath:indexPath];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"edit");
// code
return nil;
}
-(void)addMyButton
{
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod) forControlEvents:UIControlEventTouchUpInside];
button.tag = 1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
button.frame = CGRectMake(110.0, 430.0, 100.0, 40.0);
[self.view addSubview:button];
}
-(void)viewDidLoad
{
[self addMyButton]; // Call add button method on view load
n=1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(n==1){
n++;
return 10;
}
else if(n==2){
n++;
return 20;
}
else
return 30;
}
-(void) aMethod
{
if(n>=3)
{
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
//[button setBackgroundColor:[UIColor brownColor]];
}
else{
// [button setTitle:#"Show More" forState:UIControlStateNormal];
// [button setBackgroundColor:[UIColor clearColor]];
}
NSLog(#"n==>> %d",n);
[tbl reloadData];
}
An array having thirty elements when i click ok return button then it should be shows twenty elements on TableView after next clicked i should shows ten elements and so on..
Please try the edited code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(n==1)
{
n++;
return 20; //edited from return 10 to return 20-- to return 20 elements for the first time
}
else if (n==2)
{
return 30; //Return 30 when click on view more
}
}
-(void) aMethod
{
if(n==2)
{
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
//[button setBackgroundColor:[UIColor brownColor]];
}
else
{
n=1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor clearColor]];
}
NSLog(#"n==>> %d",n);
[tbl reloadData];
}
try my code and let me know if i miss anything according to your requirement
try like this....
#import "YourTableViewControllerClass.h"
#interface YourTableViewControllerClass ()
{
NSMutableArray * tableArray;
}
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
tableArray = [[NSMutableArray alloc]initWithArray:#[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10"]];
}
-(IBAction)addMoreCells // button action to add more cells
{
[tableArray addObjectsFromArray:#[#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20"]];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#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 tableArray.count ;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [tableArray objectAtIndex:indexPath.row];
return cell;
}
#end
It looks like you're almost there.
You need tableView:cellForRowAtIndexPath: from the UITableViewDataSource protocol. This method effectively links the correct index in your array to a UITableViewCell.
e.g. something like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
}
cell.textLabel.text = [self.myArray objectAtIndex:indexPath.row];
return cell;
}
Try this,
-(void)addMyButton
{
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod)forControlEvents:UIControlEventTouchUpInside];
button.tag = 1;
[button setTitle:#"Show More" forState:UIControlStateNormal];
button.frame = CGRectMake(110.0, 430.0, 100.0, 40.0);
[self.view addSubview:button];
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self addMyButton]; // Call add button method on view load
n=2;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if( [your_array count] <= (n*10)){
n=1;
return [your_array count];
}
else
{
return n*10;
}
return 0;
}
-(void)aMethod
{
n++;
if([your_array count]<=n*10){
[button setTitle:#"Return" forState:UIControlStateNormal];
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
}
else{
[button setTitle:#"Show More" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor clearColor]];
}
[tbl reloadData];
}
Also add the code to set the data in table view cell (from your array) inside this method,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can check the functionality by using the dummy code given below,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"%ld",indexPath.row+1];
return cell;
}
I've got an sectioned UITableView and want to set a label (not in the tableview) the text of the label that's on top.
I tried settings label with [label setText:#"name"]; in
(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
but that didn't work. Anyone else have ideas how to do this?
Try this
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 60)];
headerView.backgroundColor = [UIColor clearColor];
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0,0, 50, 50)];
label.backgroundColor = [UIColor yellowColor];
label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
[headerView addSubview:label];
return headerView;
}
If you're using that method you only need to return the string. It will handle creating a label for you.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"Name";
}
If you want to use your own UIView or UILabel you'll need to use a different dataSource method.
- (UIView *) tableview:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UILabel *customLabel = [[UILabel alloc] initWithFrame:CGRect(0.0,0.0,100.0,20.0)];
[customLabel setText:#"name"];
return customLabel;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
self.tableView1.tag = 1;
if ( [tableView tag] == 1 ) {
return #"TableView One Title";
}
return #"other Tableview Title";
}
My recent frustration is a UIButton subview in each UITableViewCell of my UITableView which I want to setHidden: according to a specific clause for each indexPath. My code is pretty much the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[self initCell:cell forIndexPath:indexPath];
}
[self updateCell:cell forIndexPath:indexPath];
return cell;
}
and the init and update methods are the following:
- (void)initCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
...
UIButton *btnMy = [UIButton buttonWithType:UIButtonTypeCustom];
btnMy.tag = kButtonMyTag;
[btnMy setFrame:CGRectMake(170, 45, 100, 30)];
[btnMy setBackgroundImage:[UIImage imageNamed:#"btn_image"] forState:UIControlStateNormal];
btnMy.adjustsImageWhenHighlighted = YES;
[btnMy setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btnMy.titleLabel.font = [UIFont fontWithName:#"MyFont" size:14];
[btnMy addTarget:self action:#selector(btnMyPressed:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btnMy];
UIImageView *imgViewAccessory = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"table_accessory"]];
cell.accessoryView = imgViewAccessory;
[imgViewAccessory release];
}
- (void)updateCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
UIButton *btnMy = (UIButton *)[cell viewWithTag:kButtonMyTag];
MyObject *object = (MyObject *)[self.dataSource objectAtIndex:indexPath.row];
if(object.meetsCondition)
{
btnMy.hidden = NO;
}
else
{
btnMy.hidden = YES;
}
...
}
The frustrating result is that when scrolling the button shows and hides randomly and not as expected according the if clause in the updateCell method.
Any help would be much appreciated. Thanks in advance!
You should make custom cell and depending upon the condition show and hide the button
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *nib;
static NSString *cellIdentifier= #"cell";
UITableViewCell *theCell = [self.tblView dequeueReusableCellWithIdentifier:cellIdentifier];
if([theCell.contentView subviews]){
for(UIView *view in [theCell.contentView subviews]){
[view removeFromSuperview];
}
}
if(theCell== nil)
{
nib = [[NSBundle mainBundle] loadNibNamed:#"Your custom cell name" owner:self options:nil];
theCell = [nib objectAtIndex:0];
theCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
UIButton *btn=(UIButton*)[theCell.contentView viewWithTag:101];
if(yourcondition)
//hide button
else
//show button
}
This will do
Use this code in your CellForRowAtIndexPath Also.
MyObject *object = (MyObject *)[self.dataSource objectAtIndex:indexPath.row];
if(object.meetsCondition) {
btnMy.hidden = NO;
}
else {
btnMy.hidden = YES;
}