I created a custom cell and upon click, it should display a popup.
However, when this is works successfully, it seems to create an issue where I am not able to click the delete button.
It seems that my UITapRecognizer supercedes my method to delete.(Means the popup is displayed instead when I click the delete button )
Any idea how to solve this?
Below is my code to handle tap in the cell (OfficeCell.m)
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(openOfficePopover)];
[tapGestureRecognizer setNumberOfTapsRequired:1];
[self setUserInteractionEnabled:YES];
[self addGestureRecognizer:tapGestureRecognizer];
self.textLabel.font = [UIFont boldSystemFontOfSize:15];
self.textLabel.textColor = mRgb(0x3a, 0x6c, 0x99);
}
return self;
}
Below is my code to handle the delete in the ViewController :
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
NSInteger section = [indexPath section];
if (section ==1 )
{
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source
NSInteger section = [indexPath section];
if(section == 1)
{
[_sectionOffice removeObjectAtIndex:indexPath.row];
}
[self.formView reloadData];
}
}
Just realize that the fix should be really simple :
changing 2 lines of code solve the issue :
From :
[self setUserInteractionEnabled:YES];
[self addGestureRecognizer:tapGestureRecognizer];
To :
[self.contentView setUserInteractionEnabled:YES];
[self.contentView addGestureRecognizer:tapGestureRecognizer];
Related
I'm got a tableview that displays custom view cells. In viewWillAppear i've setup a long press gesture recognizer that is on the UITableView. My long press is firing and displaying the info about the cell that has been long pressed upon. However when I let go of the press the didSelectRowAtIndexPath method is firing. Is there a way to cancel the touch after the long press fires, so that the select row doesn't get triggered?
I've seen didSelectRowAtIndexPath called after long press and that question does not seem to have an adequate answer as to how to fix the problem.
#implementation ViewController
UILongPressGestureRecognizer *lpgr;
.
.
.
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// setup long press
lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 0.5; //seconds
lpgr.delegate = self;
lpgr.cancelsTouchesInView = true;
[self.myTableview addGestureRecognizer:lpgr];
[self.myTableview.panGestureRecognizer requireGestureRecognizerToFail:lpgr]; ...
.
.
.
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint p = [gestureRecognizer locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
if (indexPath == nil) {
NSLog(#"long press on table view but not on a row");
} else {
UITableViewCell *cell = [self.myTableview cellForRowAtIndexPath:indexPath];
CensusData *currentUser;
if(self.isFiltered){
currentUser = (CensusData*)[self.filteredTableData objectAtIndex:indexPath.row];
}else{
currentUser = (CensusData*)[self.dataArray objectAtIndex:indexPath.row];
}
NSLog(#"CURRENT ROW WITH LONG PRESS: %#", currentUser.friendlyName);
}
}
}
.
.
.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
While the gesture is active (begun but not ended) disable selection on the table view...
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.myTableview.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
self.myTableview.allowsSelection = YES;
}
}
No need to set the delegate, set cancelsTouches, or implement shouldRecognize... (unless you need these for something else).
EDIT This vc is a minimally complete test. It requires a storyboard with a table view wired to the outlet and the vc as the datasource and delegate...
#import "ViewController.h"
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property(weak,nonatomic) IBOutlet UITableView *tableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[self.tableView addGestureRecognizer:gr];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"Row %ld", indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"selected %#", indexPath);
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
NSLog(#"long press began");
self.tableView.allowsSelection = NO;
} else if (gr.state == UIGestureRecognizerStateEnded) {
NSLog(#"long press ended");
self.tableView.allowsSelection = YES;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You can disable tableview then only longGesture is working properly
UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(onLongPress:)];
[self.myTableview addGestureRecognizer:longPressRecognizer];
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{
if (pGesture.state == UIGestureRecognizerStateRecognized)
{
//Do something to tell the user!
}
if (pGesture.state == UIGestureRecognizerStateEnded)
{
CGPoint p = [pGesture locationInView:self.myTableview];
NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isDescendantOfView:self.myTableview]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}
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;
}
I've been writing an app that has custom protocol to send the data from the child view to parent view the classes is
MainViewController
AddViewController (child to mainviewcontroller)
DaysViewController (child to addviewcontroller)
the custom protocol was declared in DaysViewController and implemented in AddViewController
AddViewController.h
#import <UIKit/UIKit.h>
#import "DaysViewController.h"
#import "Course.h"
#import "Student.h"
#interface AddViewController : UITableViewController<UIActionSheetDelegate,UIPickerViewDelegate,UIPickerViewDataSource,UIPickerViewAccessibilityDelegate,UITextFieldDelegate,DaysViewControllerDelegate>
{
NSArray *hoursarray;
UIActionSheet *aac;
IBOutlet UITextField *NameTx,*HoursTx,*DaysTx,*TimeTx;
Student *st;
Course *cc;
}
-(void) pickerDoneClick;
-(IBAction)fillTheOtherData;
#property (nonatomic ,strong) UIActionSheet *aac;
#end
AddViewController.m
#import "AddViewController.h"
#interface AddViewController ()
#end
#implementation AddViewController
#synthesize aac;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//viewP.frame = CGRectMake(0, 154, 320, 205);
hoursarray = [[NSArray alloc]initWithObjects:#"2",#"3",#"4", nil];
[self.tableView setScrollEnabled:NO];
[DaysTx setEnabled:NO];
[TimeTx setEnabled:NO];
[HoursTx setKeyboardType:UIKeyboardTypeDecimalPad];
cc = [[Course alloc]init];
//UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped:)];
//[self.view addGestureRecognizer:tapgr];
}
-(void)tapped:(UITapGestureRecognizer *)tap
{
[self.view endEditing:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [hoursarray count];
}
//-(IBAction)addCourse
//{
// [UIView beginAnimations:#"view" context:nil];
// [UIView setAnimationDuration:1];
// viewP.frame = CGRectMake(0, 500, 320, 205);
// [UIView commitAnimations];
//
//}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [hoursarray objectAtIndex:row];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 3)
{
aac = [[UIActionSheet alloc]initWithTitle:#"How many ?" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
UIPickerView *picker = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 44, 0, 0)];
picker.delegate = self;
picker.dataSource = self;
UIToolbar *pickerToolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[pickerToolBar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc]init];
UIBarButtonItem *flexspace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexspace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDoneClick)];
[barItems addObject:doneBtn];
[pickerToolBar setItems:barItems animated:YES];
[aac addSubview:pickerToolBar];
[aac addSubview:picker];
[aac showInView:self.view];
[aac setBounds:CGRectMake(0, 0, 320, 464)];
}
else if (indexPath.row == 2)
{
DaysViewController *days = [self.storyboard instantiateViewControllerWithIdentifier:#"Days"];
days.delegate = self;
[self.navigationController pushViewController:days animated:YES];
}
}
-(void) pickerDoneClick
{
[aac dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray
{
NSLog(#"I'm # chooseDays method");
NSLog(#"Before the add !!");
NSLog(#"chooseDays Method and the array is %#",theDaysArray);
cc.days = [NSMutableArray arrayWithObject:theDaysArray];
NSLog(#"After the add");
NSLog(#"chooseDays Method and the array is %#",cc.days);
// [self dismissViewControllerAnimated:YES completion:nil];
}
-(void)cancelChooseDays:(DaysViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)fillTheOtherData
{
cc.name = NameTx.text;
cc.hour = [HoursTx.text integerValue];
NSLog(#"The name is %# and the hour credit is %d",cc.name,cc.hour);
}
#end
DaysViewController.h
#import <UIKit/UIKit.h>
#import "Course.h"
#class DaysViewController;
#protocol DaysViewControllerDelegate <NSObject>
#required
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray;
-(void)cancelChooseDays:(DaysViewController *)controller;
#end
#interface DaysViewController : UITableViewController
{
Course *courseDays;
NSArray *days;
NSMutableArray *dayChosen;
}
#property (nonatomic,weak) id<DaysViewControllerDelegate> delegate;
-(IBAction)done:(id)sender;
-(IBAction)cancel:(id)sender;
#end
DaysViewController.m
#import "DaysViewController.h"
#interface DaysViewController ()
#end
#implementation DaysViewController
#synthesize delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
days = [[NSArray alloc]initWithObjects:#"Saturday",#"Sunday",#"Monday",#"Teusday",#"Wednesday",#"Thursday",#"Friday", nil];
dayChosen = [[NSMutableArray alloc]init];
}
- (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
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DaysCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DaysCell"];
}
cell.textLabel.text = [days objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)done:(id)sender
{
//Course *course = [[Course alloc]init];
//[course.days addObject:dayChosen];
//NSArray *daysArray = [NSArray arrayWithObject:dayChosen];
NSLog(#"The Days are %#",dayChosen);
[self.delegate chooseDays:self withArray:dayChosen];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)cancel:(id)sender
{
[self.delegate cancelChooseDays:self];
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[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
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[dayChosen addObject:[days objectAtIndex:indexPath.row]];
NSLog(#"Days are %#",dayChosen);
}
#end
MainViewController has a button that take me to AddViewController and AddViewController has same button that takes me to DaysViewController , all the views has a UITableView .
what I want to do is when I send the data from DaysViewController to AddViewController to put it in an array and dismiss the view AddViewController should show up but instead MainViewController shows and this is what I dont want it to be.
AddViewController and DaysViewController have a UINavigationController but MainViewController doesn't.
Thank you in advance.
Okay, I think I know what your problem is. In your cancel function, try and switch this line of code:
[self dismissViewControllerAnimated:YES completion:nil];
With this line of code:
[self.navigationController popViewControllerAnimated:YES];
Let me know if that helps.
I created a UISearchBar. It is working but not the way I want. If I enter any first letter on the UISearchbar and then I click on the SearchButton, it doesn't work but when I push the next controller and I come back, then I see my search result in TableView. The first time my TableView does not refresh.
Here is my custom cell class and my controller class
#synthesize myTableView;
#synthesize tabledata;
#pragma mark -
#pragma mark Initialization
#pragma mark -
#pragma mark View lifecycle
-(void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
app = (JourneyAppDelegate *)[[UIApplication sharedApplication]delegate];
sBar =[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 30)];
sBar.delegate=self;
[self.view addSubview:sBar];
searcheddata =[[NSMutableArray alloc]init];
NSLog(#"*************:%&",list);
list=[[NSMutableArray alloc]init];
tabledata =[[NSMutableArray alloc]init];
list = [app.journeyList retain];
[tabledata addObjectsFromArray:list];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100.0;
}
#pragma mark -
#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 [tabledata count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"*************:%&",list);
static NSString *CellIdentifier = #"Cell";
TJourneyListCell *cell =(TJourneyListCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[TJourneyListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
NSLog(#"%#",cell);
}
NewJourney *newjoruneobject = [tabledata objectAtIndex:indexPath.row];
cell.namelbl.text = newjoruneobject.journeyname;
cell.distancelbl.text = newjoruneobject.journeylocation;
cell.infolbl.text = newjoruneobject.journeydescription;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
#pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
// only show the status bar’s cancel button while in edit mode
[tabledata removeAllObjects];
sBar.showsCancelButton = YES;
[searchBar setShowsCancelButton:YES animated:YES];
sBar.autocorrectionType = UITextAutocorrectionTypeNo;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = NO;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[tabledata removeAllObjects];// remove all data that belongs to previous search
if([sBar.text length] != 0)//|| searchText==nil)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"journeyname contains[cd] %#", searchBar.text];
[tabledata addObjectsFromArray:[list filteredArrayUsingPredicate: predicate]];
[myTableView reloadData];
return;
}
NSLog(#"Counter:-'%d'",[tabledata count]);
[myTableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{ // if a valid search was entered but the user wanted to cancel, bring back the main list content
[tabledata removeAllObjects];
[tabledata addObjectsFromArray:list];
#try
{
[myTableView reloadData];
}
#catch(NSException *e)
{
}
[sBar resignFirstResponder];
sBar.text = #" ";
}
// called when Search (in our case “Done”) button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
myTableView.allowsSelection = YES;
myTableView.scrollEnabled = YES;
[myTableView reloadData];
}
- (void)dealloc {
[super dealloc];
[mLable1 release];
[myTableView release], myTableView = nil;
[tabledata dealloc];
}
#end
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
searchBar.showsCancelButton = NO;
[myTableView reloadData];
}
I was having difficulties with this as well until I got to this post. I looked through your functions and decided to throw the reload data in the function above it works fine now! Hope this helps!
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[tableView reloadData];
}
You can use this delegate method to reload table, after search table disappears:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
Swift version
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false //Local variable used to manipulate your cells
self.newsTableView.reloadData()
}
I'd like my UITableView to behave like the the table in the Contacts editor, i.e. the user should hit Edit and an "add new category" row should appear at the bottom of each section.
I'm using the below code to do this, but the problem is that there is no smooth transition as there is in Contacts. Instead, the new row suddenly appears. How can I get the animation?
Also, how do I respond to clicks on the "add new category" row? The row is not clickable in my current implementation.
Do I need to reload the data when the user starts editing? I am doing this because otherwise the insertion rows are never drawn.
Thanks.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
[tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section {
// ...
if( self.tableView.editing )
return 1 + rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// .....
NSArray* items = ...;
if( indexPath.row >= [items count] ) {
cell.textLabel.text = #"add new category";
}
// ...
return cell;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray* items = ...;
if( indexPath.row == [items count] )
return UITableViewCellEditingStyleInsert;
return UITableViewCellEditingStyleDelete;
}
I was missing one thing. In setEditing:, instead of calling reloadData I should have done:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController
NSMutableArray* paths = [[NSMutableArray alloc] init];
// fill paths of insertion rows here
if( editing )
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
else
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
[paths release];
}
Responding to clicks on the row might be done in the didSelectRowAtIndexPath method, for indexPath.row == [items count]. For the animation, I suggest taking a look here, at the insertRowsAtIndexPaths:withRowAnimation: method. There's a post on how to use it here.
An unwanted side effect of the highlighted solution is that the "add" row is inserted also when the user just swipes one single row (provided that swiping is enabled). The following code solves this dilemma:
// Assuming swipeMode is a BOOL property in the class extension.
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
// Invoked only when swiping, not when pressing the Edit button.
self.swipeMode = YES;
}
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
self.swipeMode = NO;
}
Your code would require a small change:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController
if (!self.swipeMode) {
NSMutableArray* paths = [[NSMutableArray alloc] init];
// fill paths of insertion rows here
if( editing )
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
else
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
[paths release];
}
}