UITableViewCell delete does not use proper UITableViewRowAnimation - ios

When a row is deleted it always slides to left no matter what animation value I pass. I would like it to slide up similar to many of the stock apps.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
self.tableData = [][[self.tableData mutableCopy] removeObjectAtIndex:indexPath.row] copy];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
}
Here is the full tableview controller code, it is has a lot in it. That is the reason I didn't post it at first.
#interface FMListViewController ()
#property (strong) NSArray *currentLocations;
#property (assign) BOOL isEditing;
#end
#implementation FMListViewController
- (void)viewDidLoad {
[super viewDidLoad];
UISegmentedControl *viewType = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"List", #"Map", nil]];
CGRect viewTypeRect = viewType.frame;
viewTypeRect.size.width = 150.0f;
viewType.frame = viewTypeRect;
viewType.selectedSegmentIndex = 0;
[viewType addTarget:self action:#selector(viewTypeChange:) forControlEvents:UIControlEventValueChanged];
self.navigationItem.titleView = viewType;
self.currentLocations = [[FMLocations sharedManager] allLocations];
//watch for weather updates
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(weatherUpdated) name:#"weatherUpdated" object:nil];
//watch for changes to saved locations
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(locationsUpdated) name:#"locationsUpdated" object:nil];
self.isEditing = NO;
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// this UIViewController is about to re-appear, make sure we remove the current selection in our table view when swiping back occurs
NSIndexPath *tableSelection = [self.tableView indexPathForSelectedRow];
[self.tableView deselectRowAtIndexPath:tableSelection animated:NO];
[self.navigationController setToolbarHidden:YES animated:NO];
}
- (void)viewTypeChange:(UISegmentedControl *)segControl{
NSLog(#"change to map");
[(FMNavController *)[self navigationController] changeViewType];
segControl.selectedSegmentIndex = 0;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)weatherUpdated{
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
- (void)locationsUpdated{
if(self.isEditing){
self.currentLocations = [[FMLocations sharedManager] savedLocations];
}else{
self.currentLocations = [[FMLocations sharedManager] allLocations];
}
[self.tableView reloadData];
}
#pragma mark - Table Editing Stuff
- (IBAction)toggleEditing:(id)sender{
if(self.isEditing){
self.isEditing = NO;
self.currentLocations = [[FMLocations sharedManager] allLocations];
[self.tableView reloadData];
UIBarButtonItem *newRightItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(toggleEditing:)];
self.navigationItem.rightBarButtonItem = newRightItem;
[self.tableView setEditing:NO animated:YES];
}else{
self.isEditing = YES;
self.currentLocations = [[FMLocations sharedManager] savedLocations];
[self.tableView reloadData];
UIBarButtonItem *newRightItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(toggleEditing:)];
self.navigationItem.rightBarButtonItem = newRightItem;
[self.tableView setEditing:YES animated:YES];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0 && [[FMLocations sharedManager] currentLocation] && !self.isEditing){
return NO;
}
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
NSMutableArray *newLocations;
int arrayOffset = 0;
if([[FMLocations sharedManager] currentLocation] && !self.isEditing){
arrayOffset = -1;
}
newLocations = [[[FMLocations sharedManager] savedLocations] mutableCopy];
int itemToRemove = (int)indexPath.row + arrayOffset;
if(itemToRemove < 0 || itemToRemove > [newLocations count]){
NSLog(#"invalid item to remove");
}else{
[newLocations removeObjectAtIndex:itemToRemove];
[[FMLocations sharedManager] saveSavedLocations:[newLocations copy]];
if(self.isEditing){
self.currentLocations = [[FMLocations sharedManager] savedLocations];
}else{
self.currentLocations = [[FMLocations sharedManager] allLocations];
}
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
}
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0 && [[FMLocations sharedManager] currentLocation] && !self.isEditing){
return NO;
}
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
NSMutableArray *editableLocations = [[[FMLocations sharedManager] savedLocations] mutableCopy];
if(editableLocations && [editableLocations count] > sourceIndexPath.row && [editableLocations count] > destinationIndexPath.row){
NSInteger fromIndex = sourceIndexPath.row;
NSInteger toIndex = destinationIndexPath.row;
id object = [editableLocations objectAtIndex:fromIndex];
[editableLocations removeObjectAtIndex:fromIndex];
[editableLocations insertObject:object atIndex:toIndex];
[[FMLocations sharedManager] saveSavedLocations:[editableLocations copy]];
}
}
#pragma mark - Refresh control action
- (IBAction)doRefreshTable:(id)sender{
[[ForecastManager sharedManager] updateForecasts];
}
#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.currentLocations count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//NSLog(#"getting cell");
FMTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"FMLocationCell" forIndexPath:indexPath];
NSDictionary *theLocation = [self.currentLocations objectAtIndex:indexPath.row];
// Configure the cell...
cell.locationLabel.text = [[theLocation objectForKey:#"name"] uppercaseString];
WeatherObject *locationWeather = [[ForecastManager sharedManager] weatherObjectForLocation:[[theLocation objectForKey:#"id"] intValue]];
[cell setCurrentTemp:locationWeather.currentTemp];
[cell configureForecastViews:locationWeather.forecastObjects];
[cell.weatherPreviewContainer setNeedsDisplay];
return cell;
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if([segue.identifier isEqualToString:#"showLocation"]){
FMDetailViewController *detailController = [segue destinationViewController];
NSDictionary *theLocation = [self.currentLocations objectAtIndex:self.tableView.indexPathForSelectedRow.row];
detailController.navigationItem.title = [theLocation objectForKey:#"name"];
detailController.detailLocation = theLocation;
}
}

You can try below solutions:
1) Replace your line with the below one
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationTop];
2) Change the code with the below one:
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
Hope this helps!

please try with that
don't delete cell directly first make its cellheight to zero using. NSIndexPath *deleteIndexPath;
wirte below code before delete
[tbl beginUpdates];
deleteIndexPath = indexPath;
[tbl reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tbl endUpdates];
and in set hight method use
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ if (indexPath == deleteIndexPath) {
return 0;
}
return 50;
}

Related

Buggy swipe to delete display on one more row after each delete

I'm having a weird issue on UITableView delete action since iOS 11.
Here's the relevant TableView code :
#implementation ChatMessageListViewController(TableView)
#pragma mark - table view datasource/delegate
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
NSMutableArray *rowActions = [NSMutableArray array];
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Delete" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self deleteMessageAtIndexPath:indexPath];
}];
delete.backgroundColor = [UIColor redColor];
[rowActions addObject:delete];
return [rowActions copy];
}
- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:#"threadID"];
[self.tableView beginUpdates];
[self.messageArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
#weakify(self);
[UIUtil showLoadingHudWithText:WELocalString(#"message_remove_thread_loading_text", #"Deleting...", #"删除中...")];
[[AsyncUtil sharedInstance] dispatch_background_network:^{
DBManager *db = [[DBManager alloc] init];
[db deletetableData:[NSString stringWithFormat:#"singleChat WHERE threadID = '%#' ",threadID] ];
[[MemChatThreadMessages sharedInstance] removeThread:threadID];
NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
[[AsyncUtil sharedInstance] dispatch_main:^{
[UIUtil hideLoadingHuds];
#strongify(self);
if(self == nil) return ;
if([result[#"result"] isEqualToString:#"success"]){
}else{
[UIUtil showErrorMessage:WELocalString(#"message_remove_thread_error", #"Cannot delete this thread", #"不能删除该会话!")];
}
[self.tableView reloadData];
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messageArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if ([(NSString *)[messageInfo objectForKey:#"isAnnouncement"] isEqualToString:#"1"]) {
return 80;
}else if ([[messageInfo objectForKey:#"chatTag"] isValidString]){
return 80;
}else if([self isSpecialMessage:messageInfo]){
return 80;
}else{
return 67;
}
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"message";
if(self.events == nil){
NSDictionary * d = [WEUtil getMyEventListCache];
self.events = [[NSMutableDictionary alloc] init];
for(NSDictionary * eventSummary in d[#"events"]){
NSString * eventID = eventSummary[#"eventid"];
[self.events setObject:eventSummary forKey:eventID];
}
}
UserMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UserMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row >= [self.messageArray count]){
TERMINATE_WITH_NIL_CELL;
}
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:messageInfo]){
[cell configureCellWithMessageDict:messageInfo];
}else{
[cell configureCellWithNewMessageDict:messageInfo withEvents:self.events];
}
return cell;
}
#pragma mark - Navigation
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:msgThreadDict]){
[self tableView:tableView didSelectNormalRowAtIndexPath:indexPath];
}else{
NSString * event = msgThreadDict[#"event"];
if([event isValidString]){
if([event isEqualToString:#"no_event_messages"]){
[UIUtil showErrorMessage:#"no event id"];
}else{
[BackendTracking trackingWithAction:#"open_special" withLabel:#"threads_list"];
SpecialTopicListViewController * special = [[SpecialTopicListViewController alloc] init];
special.tracking_src = #"tab";
[self.navigationController pushViewController:special animated:YES];
}
}
}
}
-(void) tableView:(UITableView *)tableView didSelectNormalRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
NSString *threadID = [msgThreadDict objectForKey:#"threadID"];
NSString *jid = [msgThreadDict objectForKey:#"jid"];
[GATracking trackCategory:#"message" withAction:#"thread_list_item_click" withLabel:threadID];
[[MemChatThreadMessages sharedInstance] setCurrentThreadID:threadID];
PrivateMessageViewController * chatVC = [[PrivateMessageViewController alloc] init];
chatVC.threadID = threadID;
chatVC.targetJID = jid;
chatVC.targetName = [msgThreadDict objectForKey:#"name"];
chatVC.unreadMsgNumber = [[self.messageArray objectAtIndex:indexPath.row][#"unreadCnt"] integerValue];
if ([(NSString *)[msgThreadDict objectForKey:#"isGroup"] isEqualToString:#"1"]) {
chatVC.isGroup = YES;
}else{
chatVC.isGroup = NO;
}
chatVC.src = #"list";
WELogInfo(#"click message");
[self.navigationController pushViewController:chatVC animated:YES];
}
#end
With the update and the changes using those trailing swipe actions there is another View appended before each time I delete an entry (until it doesn't work anymore). I've tried disabling the full trail or implementing iOS 11 trailingSwipeActionsConfigurationForRowAtIndexPath but I can't resolve this issue so far.
Do you see something wrong in the code? The main controller code is in another file.
Try reloading after you delete, after this line
[self.tableView endUpdates];
I think you removed the data from messageArray but as you are not reloading just after that so table view count is still 2 and you are reloading inside the block which might be taking time.
And one more thing you already removing data from messageArray, and then removing from db, So if you fail to remove it from db you are showing its not removed but for user it will be removed, as its no longer in message array

How to pass value in select UITableViewCell Row

I have UITableViewCell, cell indexing category wise and expand cell click on header, and load data by JSON. I want to select cell and pass data another view controller. I try to many times but pass data only first cell. I clicked another cell so this condition pass data first cell. Can't send particular cell data. How it possible . please help.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSArray *statuses = [json objectForKey:#"status"];
names=[[NSMutableArray alloc]initWithArray:[statuses valueForKey:#"business_category_name"]];
business_details_array=[[NSMutableArray alloc]initWithArray:[statuses valueForKey:#"business_details"]];
for (int i=0; i<[names count]; i++) {
[arrayForBool addObject:[NSNumber numberWithBool:NO]];
}
[self.tabel_view reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return names.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[arrayForBool objectAtIndex:section] boolValue]) {
return [[business_details_array objectAtIndex:section] count];
}
else
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 70;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionHeaderView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,70)];
sectionHeaderView.backgroundColor=[UIColor grayColor];
sectionHeaderView.tag=section;
UIView *sectionsubHeaderView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,60)];
sectionsubHeaderView.backgroundColor=[UIColor blueColor];
UIImageView *arrow=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0,60, 60)];
[arrow setImage:[UIImage imageNamed:#"arrow.png"]];
UILabel *Lbl=[[UILabel alloc]initWithFrame:CGRectMake(60, 0,tableView.frame.size.width-60, 60)];
Lbl.text=[names objectAtIndex:section];
Lbl.textColor=[UIColor whiteColor];
[sectionsubHeaderView addSubview:arrow];
[sectionsubHeaderView addSubview:Lbl];
[sectionHeaderView addSubview:sectionsubHeaderView];
UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sectionHeaderTapped:)];
[sectionHeaderView addGestureRecognizer:headerTapped];
return sectionHeaderView;
}
- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
if (indexPath.row == 0) {
BOOL collapsed = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
for (int i=0; i<[names count]; i++) {
if (indexPath.section==i) {
[arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]];
}
}
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MemberTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ht"];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString*title_str=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"name"] objectAtIndex:indexPath.row]];
cell.title.text= title_str;
[titles addObject:title_str];
NSLog(#"get %#",titles);
cell.email.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"email"] objectAtIndex:indexPath.row]];
//[emailary addObject:cell.email.text];
cell.address_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"address"] objectAtIndex:indexPath.row]];
//[adrsary addObject:cell.address_lbl.text];
cell.phone_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"phone"] objectAtIndex:indexPath.row]];
// [phoneary addObject:cell.phone_lbl.text];
cell.web_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"website"] objectAtIndex:indexPath.row]];
//[websiteary addObject:cell.web_lbl.text];
cell.sens_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"member_since"] objectAtIndex:indexPath.row]];
//[sensary addObject:cell.sens_lbl.text];
cell.des_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"des"] objectAtIndex:indexPath.row]];
//[desary addObject:cell.des_lbl.text];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"img_url"] objectAtIndex:indexPath.row]]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
cell.image_view.image =image;
//[images addObject:cell.image_view.image];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showRecipeDetail"])
{
NSIndexPath *indexPath = [self.tabel_view indexPathForSelectedRow];
member_details *destViewController = segue.destinationViewController;
destViewController.hello = [titles objectAtIndex:indexPath.row];
}
}
As you have directly joined segue from tableview, it's not proper way to do that. Instead of you have to joined segue by controller to controller. So before getting proper selected row index, your view controller push fast and you are always getting 0 index.
Instead of writing logic in prepareForSegue, you can do the same stuff in didSelect method of UITablView.
For that you have to find your destination view controller from storyboard. And set the data to required property.
EDIT
Remove your prepare segure logic and do this in didSelect
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:[NSBundle mainBundle]];
YourDestinationVC *vc =[[storyboard instantiateViewControllerWithIdentifier:#"YourDestinationVC"]; //#"YourDestinationVC" is storyboardID for your destination view controller
vc.hello = [titles objectAtIndex:indexPath.row];
[[self navigationController] pushViewController:vc animated:YES];
}
Here is screenshot :
You should create your segues between viewcontrollers.
Do not create segue from cell to viewcontrollers.
Then you should call
[self performSegueWithIdentifier:#"showRecipeDetail" sender:self];
after updating the table in didSelectRowAtIndexPath
Try this remove prepare for prepareForSegue and in didselectrowatindexpath add.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
member_details *destViewController = [[member_details alloc]init];
destViewController.hello = [titles objectAtIndex:indexPath.row];
[[self navigationController] pushViewController:destViewController animated:YES];
}
Try This
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"showRecipeDetail" sender:[YOUR_ARRAY objectAtIndex:indexPath.row]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showRecipeDetail"])
{
member_details *destViewController = segue.destinationViewController;
destViewController.hello = sender;
}
}

UITableView - move people from one section to another

I would like to create a tableview where I can move people from different departments into other departments, and I have some code posted below.
I have an issue with this, I can never seem to get it to get the usual ui gadget to move rows. I don't want the user to edit/delete the rows; simply move them about however the "move" buttons never seem to appear.
Is there something I am doing wrong?
Also I am not sure if I am doing the move code right.
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Departments";
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.tableView.allowsSelectionDuringEditing = YES;
_objects = [NSMutableArray array];
NSDictionary *sales = #{ #"name" : #"sales",
#"employees" : #[ #"Mike", #"Tom", #"Alex"] };
NSDictionary *marketing = #{ #"name" : #"marketing",
#"employees" : #[ #"Heather", #"Richard", #"Simon"] };
[_objects addObject:sales];
[_objects addObject:marketing];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
}
#pragma mark - IBActions
-(IBAction) editButton:(id)sender
{
[self setEditing:!self.editing animated:YES];
}
#pragma mark - UITableView delegate
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [_objects count];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
NSArray *employees = department[#"employees"];
return [employees count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
// Configure the cell...
NSDictionary *department = [_objects objectAtIndex:indexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:indexPath.row];
cell.textLabel.text = employeeName;
return cell;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
return department[#"name"];
}
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
if( fromIndexPath == toIndexPath ) return;
NSDictionary *department = [_objects objectAtIndex:fromIndexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:fromIndexPath.row];
[self.tableView beginUpdates];
[_objects removeObjectAtIndex:fromIndexPath.row];
[_objects insertObject:employeeName atIndex:toIndexPath.row];
[self.tableView endUpdates];
[tableView reloadData];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
if (indexPath.section == 1 && [_objects count] > 1)
{
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if(editingStyle == UITableViewCellEditingStyleDelete){
[_objects removeObjectAtIndex:indexPath.row];
NSArray *rows = [NSArray arrayWithObject:indexPath];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}
call this method after your array initialised. [self.tableView reloadData]
This will load the table data once again.

SearchBar clickable results - Core Data

I am fairly new to Xcode so I have been using a tutorial on how to implement a SearchBar in my notes app. The SearchBar retrieves the data from the table view but when I click on it it doesn't take me to the page. How would I fix this problem in UIStoryboardSegue keeping in mind I'm new to all this stuff! Thanks in advance:3
#import "DeviceViewController.h"
#import "DeviceDetailViewController.h"
#interface DeviceViewController ()
#property (strong) NSMutableArray *devices;
#end
#implementation DeviceViewController
{
NSArray *searchResults;
}
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
//label.backgroundColor = [UIColor clearColor];
label.font = [UIFont fontWithName:#"HelveticaNeue-thin" size:28];
//label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
label.textColor = [UIColor blackColor];
self.navigationItem.titleView = label;
label.text = #"TapNotes";
[label sizeToFit];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Device"];
self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[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
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return self.devices.count;
}
//return self.devices.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; }
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
[cell.textLabel setText:[NSString stringWithFormat:#"%#", [device valueForKey:#"name"]]];
[cell.detailTextLabel setText:[NSString stringWithFormat:#"%#",[device valueForKey:#"version"]]];
if (tableView == self.searchDisplayController.searchResultsTableView) {
device = [searchResults objectAtIndex:indexPath.row];
} else {
[self.devices objectAtIndex:indexPath.row];
}
// cell.thumbnailImageView.image = [UIImage imageNamed:recipe.image];
return cell;
}
- (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
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete object from database
[context deleteObject:[self.devices objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
// Remove device from table view
[self.devices removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
/*
// 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;
}
*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"UpdateDevice"]) {
NSManagedObject *selectedDevice = [self.devices objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
NSIndexPath *indexPath = nil;
//Device *device = nil;
if (self.searchDisplayController.active) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
_devices = [searchResults objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
_devices = [_devices objectAtIndex:indexPath.row];
}
DeviceDetailViewController *destViewController = segue.destinationViewController;
destViewController.device = selectedDevice;
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [_devices filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
#end
A UIStoryboardSegue can only be connected via a storyboard. Since you are presenting your search data through the UISearchDisplayController, you need to implement tableView:didSelectRowAtIndexPath:. In this method you need to make sure you are only performing a push to a new view controller when you are receiving events from the tableview connected to UISearchDisplayController In this method I would recommend you to use performSegueWithIdentifier: and manually connect a segue in you storyboard. See this answer for more details on how to create a manual segue: https://stackoverflow.com/a/17012857/1049509

setEditing method causing SIGABRT

I'm working form the big nerd ranch book, iphone programming. I'm working through Chapt 11 where you implement your own setEditing method:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if( editing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
}
else {
/*
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
*/
}
}
When I run this the whole app does a Sigabort without any info other than that. The line that seems to cause the problem is this one:
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
I'm not sure what I'm doing wrong. What else would be good to see?
This is the whole file:
//
// TeamsViewController.m
// TeamTrackerClient
//
// Created by Mark Steudel on 3/4/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "TeamsViewController.h"
#import "Team.h"
#implementation TeamsViewController
-(id) init
{
self = [super initWithStyle:UITableViewStyleGrouped];
teams = [[NSMutableArray alloc] init];
Team *team = [[Team alloc] init];
team.teamName = [NSString stringWithFormat: #"Fighting Axons"];
team.teamCode = [NSString stringWithFormat: #"FA1"];
[teams addObject:team];
Team *team2 = [[Team alloc] init];
team2.teamName = [NSString stringWithFormat: #"Pipers Peddlers"];
team2.teamCode = [NSString stringWithFormat: #"PP1"];
[teams addObject:team2];
return self;
}
- (id) initWithStyle:(UITableViewStyle)style
{
return [self init];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (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.
}
#pragma mark - View lifecycle
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
}
*/
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (UIView *) headerView
{
if( headerView)
return headerView;
UIButton *editButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[editButton setTitle: #"Edit" forState: UIControlStateNormal];
float w = [[UIScreen mainScreen] bounds].size.width;
CGRect editButtonFrame = CGRectMake(8.0, 8.0, w - 16.0, 30.0);
[editButton setFrame:editButtonFrame];
[editButton addTarget:self
action:#selector(editingButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
CGRect headerViewFrame = CGRectMake(0, 0, w, 48);
headerView = [[UIView alloc] initWithFrame:headerViewFrame];
[headerView addSubview:editButton];
return headerView;
}
- (void) editingButtonPressed: (id) sender
{
if( [self isEditing] ) {
[sender setTitle:#"Edit" forState:UIControlStateNormal];
[self setEditing:NO animated:YES];
}
else {
[sender setTitle: #"Done" forState:UIControlStateNormal];
[self setEditing:YES animated:YES];
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [self headerView];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return [[self headerView] frame].size.height;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
Team *t = [teams objectAtIndex:[sourceIndexPath row]];
[teams removeObjectAtIndex:[sourceIndexPath row]];
[teams insertObject:t atIndex:[destinationIndexPath row]];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if( editingStyle == UITableViewCellEditingStyleDelete ) {
[teams removeObjectAtIndex:[indexPath row]];
[tableView deleteRowsAtIndexPaths: [NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if( editing) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
}
else {
/*
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[teams count] inSection:0];
NSArray *paths = [NSArray arrayWithObject:indexPath];
[[self tableView] deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
*/
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int numberOfRows = [teams count];
if( [self isEditing] )
numberOfRows++;
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if( !cell ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
if( [indexPath row] < [teams count] ) {
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
}
else {
[[cell textLabel] setText: #"Add New Item ... "];
}
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
return cell;
}
#end
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationLeft];
this make the table view reload data ..and check the data in its datasource methods..
i believe it is crashing on
Team *t = [teams objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[t teamName]];
there might be no objects in the teams array on here for the new index paths...
check by breakpointing here..

Resources