iOS5 - Limit allowsMultipleSelection - uitableview

I need to limit the number of multiple selection in a Table View, but I don't have any idea for where can I begin.
Thanks and regards!

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.indexPathsForSelectedRows.count > 5)
return nil;
else
return indexPath;
}

Create a NSMutableArray. Whenever someone selects a cell, check the number of items already in the array. If it's less than your limit, put a reference to that cell's backing data into your array. If it has reached its limit, either ignore the selection or replace a previous selection...whichever makes sense for your app.

Related

How to Save UITableViewController cells after rearrange to NSUserDefaults

I've an iOS application developed using Objective-C & Xcode 6.4
Right know I'm working on manually rearranging the UITableViewController cells, everything working great. But after I press the bar button EDIT and the "3 underlines" appear to drag the cell anywhere I want in the UITableViewController, (( I can't save what I did )). So how could I do a Persistent save the changes done to the table cells location ?? I mean, How to save The new rearranged NSMutableArray to a Property list -NSUserDefaults-.
I'm using a Mutable Array to display the table's cells and these methods below:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
FileWML *fileWML = [self.filesWML objectAtIndex:sourceIndexPath.row];
[self.filesWML removeObjectAtIndex:sourceIndexPath.row];
[self.filesWML insertObject:fileWML atIndex:destinationIndexPath.row];
}
PLUS would someone tell me how I can make the edit button display the word Done, while editing ?
(( I can't save what I did )) means: after I do the rearranging order I want, and then I go to the home view then I get back to the table view I edit and rearrange, the rearranging order I did get back to the default order. So, all the rearranging I did is gone.
Thanks and every help is appreciated.
You have to load your datas from your file in an array. This array will be your tableView dataSource.
When a row is moved, in the delegate method you have to change the object's place in the array. Your array should always be the same as your tableview !
Once the editing of the tableview is done you save the array in the file. The previous content in file should be erased. Then you reload your datas ([tableView reloadData].

How to disable all unselected cells in a UITableView

Is there a way to disable all of the cells within a UITableView that aren't being used? Within my application a user chooses a max of two cells and after two cells are selected I want all other cells to be disabled but I can't figure it out. Any help would be greatly appreciated, thanks!
You don't want to disable the rows, you want to prevent the user from selecting additional rows, right?
Implement the tableView:willSelectRowAtIndexPath: delegate method. If there are already two rows selected you should return nil, otherwise return the index path.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (/* check if there are already two selected rows */) {
return nil;
} else {
return indexPath;
}
}

UITableView remove multiple row in multiple sections and save to .plist

There have been lots of great answers on Stack overflow about this topic but I cant find anything specific enough to my cause so I will ask you guys for your help.
I have a TableView which access a .plist of information. The information in the .plist is sorted into Arrays of Dictionaries. So section 1 may have 3 dictionaries of info and section 2 may have 4...
What I need to do is be able to select multiple rows in the tableView (which is already set up) and then delete the rows from the tableView (which is also set up), but I cannot seem remove and update the .plist without it crashing. Here is my code below:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.tableView.isEditing)
{
_rowsToDelete = [[NSMutableArray alloc] initWithArray:[self.tableView indexPathsForSelectedRows]];
}
Inside of the DeleteRows method I have tried a number of actions but basically I need to access the .plist again and remove the selected index's from the tableView and re-save the .plist.
The best result I have got so far is that I can delete multiple rows inside of one section however selecting multiple rows in multiple sections crashes. One answer suggested using a Case: by Case: situation on each section however the number of sections changes dynamically.
I apologise for the lack of information around the exact code used etc... but I am hoping someone can suggest the best solution for this kind of scenario.
Thanks in advanced, T
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// This method will be called for each cell you have tapped
// You cant write here any code for deletion here
}
Instead try below mentioned approach - this works for single cell deletion
However you can deleteRowsAtIndexPaths takes an array of section & row that is NSIndexPath instance
- (IBAction)actionDeleteCell:(UIButton *)sender {
// below code for getting selected cell row and its section
UIView *view = sender.superview;
while (view && ![view isKindOfClass:[UITableViewCell self]]) view = view.superview;
UITableViewCell *cell = (UITableViewCell *)view;
indexPathForDeletion = [self.tableViewListViewVC indexPathForCell:cell];
NSLog(#"cell is in section %d, row %d", indexPathForDeletion.section, indexPathForDeletion.row);
//below code for deletion from your datasource and then delete from tableview
[self.dataArray removeObjectAtIndex:indexPathForDeletion.row];
[self.tableView deleteRowsAtIndexPaths:#[indexPathForDeletion]];
}

Change UITableView delete button text after it's first shown (in editing mode)

I would like to change the delete text displayed by a UITableView once editing mode has begun.
The delegate method:
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
is called only when the deleteButton at index path is displayed for the first time, but if my model changes beneath it I need to update this text. Is it possible to cause this method to be called again without reloading the entire section? See code below, and thank you for your help in advance.
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
ContainerTableViewCell *cell = (ContainerTableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];
if ([cell.editPhotos count] > 0) {
return [NSString stringWithFormat:#"Delete %d photos", [cell.editPhotos count]];
}
else{
return #"Delete Section";
}
}
For a bit of context I have a UICollectionView nested within a UITableViewCell, a notification is sent when a cell is selected. I have tried reloading the section with:
[self.tableView reloadRowsAtIndexPaths:#[[self.tableView indexPathForCell:cell]] withRowAnimation:UITableViewRowAnimationNone];
but this is undesirerable because it causes a jump in the tableview and does not display the selection correctly. I have also tried:
[self.tableView.delegate tableView:self.tableView titleForDeleteConfirmationButtonForRowAtIndexPath:[self.tableView indexPathForCell:cell]];
in desperation. While this does cause the correct method to be called it does not change the delete text.
I just wrote a rudimentary test app where it works as expected.
I think maybe the way you get your data is not the best approach. You are querying a cell that is presumably dequeued and thus might not contain the most up-to-date information.
Instead, you should strive to achieve a true MVC pattern where your data is independent from your views, including collection view cells.
I found a solution to this problem although it is a bit of a hack. The delegate method
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
is called once for each cell every time the UITableView enters edit mode. Therefore in order to have the title change when the data changes I toggled the edit mode, using a bool to indicate that I wished to save selected information ie:
cell.retainEditSelection = YES;
[self.tableView setEditing:NO animated:NO];
[self.tableView setEditing:YES animated:NO];
cell.retainEditSelection = NO;
I use this every time something is selected that should change my delete text. Hope this helps .

Best approach: Displaying a "nothing here, yet" screen instead of empty tableView cells

When opening a UITableViewController, I'd like to display a screen saying "nothing here, yet" (c.f. screenshot of the Dropbox App below) instead of empty rows when there are no sections/rows. This is done in multiple Apps already, but I'd like to know if there is a recommended way of achieving this.
I can imagine multiple ways of doing this, including
adding a UIView as a subView to the view of the tableViewController
switching to a UIViewController and implementing the tableView behavior on my own
setting the UIView as the backgroundView and hiding the tableView cells
Thank you for all your ideas!
The way I usually do it, is displaying a single custom cell when there's nothing to display.
There is a new (as of June 2014) library called DZNEmptyDataSet handling exactly this case. It uses the first approach (UIView as a subview) described in the question. Pretty neat realisation.
You must be having some data array through which you can define few things, in table view.. You can achieve this in your tableview only with its delegate methods..
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if([dataArr count] == 0)
return 1;
return [dataArr count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if([dataArr count]==0){
return self.view.frame.size.height;
}
return 44.0;
}
and then
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if([dataArr count]==0){
//Create a cell with the no data image
tableView.scrollEnabled=NO;
}else{
//Create your default cell with data..
tableView.scrollEnabled=YES;
}
return nil;
}
I am just giving you an idea, its your choice of using it..

Resources