I created an iOS application based on navigation-based application template, the application is backed by Core Data framework.
When clicking on Edit button, I want the rows to be reorder-able and delete-able.
When constructing cells, I added this line:
cell.showsReorderControl = YES;
And tableView:canMoveRowAtIndexPath: method returns YES.
But the reorder control isn't displayed in the row, Am I missing something?
From the UITableViewCell showsReorderControl docs:
For the reordering control to appear, you must not only set this
property but implement the UITableViewDataSource method
tableView:moveRowAtIndexPath:toIndexPath:. In addition, if the data
source implements tableView:canMoveRowAtIndexPath: to return NO, the
reordering control does not appear in that designated row.
The UITableView also has to be in editing mode, which it's not in by default. Usually you use a button or some other control to toggle between editing mode. To put the table view in editing mode (we assume you have a UITableViewController and your tableView property is properly set, if not, adjust for your environment):
// This line somewhere inside the UITableViewController will
// animate in the various editing controls and make sure they
// show up on your table.
[[self tableView] setEditing:YES animated:YES];
try this . . .you have to implement these two methods to get that reorder control in editing mode
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
}
Related
I have created a table view and in its header I have set a title which will change at runtime depending on the previous view's table view click. Now initially while loading the table view header title is not updating with the latest selections, instead once I scroll down or up it updates immediately because I am setting the title in viewForHeaderInSection: method. Is it possible to update the header of section at the initial stage (i.e.. before scrolling.)
TIA
The obvious answer is reload tableview on appropriate callback method. For this problem I think viewWillAppear:(BOOL)animated selector is a good point to override. You should add this method to your tableViewController:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
Use the delegate/datasource method (you can use a public property that you set from the previous view controller):
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
i use same uiviewcontroller's instance in different tabs.
there is a uitableview in viewcontroller.
in firstviewController instance, i dont wanna edit the uitableview.
in the second one i use edit mode for tableview.
thats why i want to show or hide this method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
is it possible to make an if statement like this:
#if (editingOK)
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
....some codes
}
#endif
editing OK is a BOOL property.
if you ask why i want it, because if the user swipes on the cell, it display Delete button.
i just want it if my editingOK=YES.
The #if/#endif syntax is used for conditional compilation: it lets you modify your program at compile time based on build configuration. Read about the "C preprocessor" to learn more.
If you are, as you say, using the same object instance as the delegate of different UITableViews, you must have some way to determine which table you are dealing with.
What you need to do is implement an additional method:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
That method is called when the user swipes the cell, and you can decide if a delete button should appear or not, then return the appropriate UITableViewCellEditingStyle constant.
Isn't editability controlled by calling the setEditing method of the UITableViewController? So you could set that depending on whether or not you want to enable editing, w/o this #ifdef ugliness.
Hi
I've got simple question which I don't know how to answer.
In my app I've got UITableViewController with cells. When I select one item (cell) it's getting higlighted and in other thread I'm loading chunk of data to display to the user (after load is done new VC is pushed). When doing it with thread user still can interact with application like, going back to other NavController and I do want that to happen. What I don't want to happen is that when loading isn't complete user can select other cell in table and it get's highlted. How I can prevent that (only highlit, I'm checking if there was a previous request so I'm not putting another thread untli previous request is done).
So basicly my question is, how can you foribd user from interacting with table view controller?
Set the selectionStyle of the UITableViewCell's to UITableViewCellSelectionStyleNone.
You can use the following to check if row can be selected:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (rowSelected) {
return nil;
}
return indexPath;
}
So, you only select it if no row is selected. In your didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
rowSelected = YES;
// call method that is going to do something and mark rowSelected = NO;
}
You can deselect the row by using
[[tableView cellForRowAtIndexPath:indexPath] setSelected:NO animated:YES];
There is a risk that your users will be confused. A highlight is not enough. There should be very clear visual feedback that a network opperation is ongoing and that different rules apply.
either push the details view immediately after the user selected a row and show an activity indicator in there.
or give the whole table view a different look while loading data for the selected row: e.g. Show activity indicator in the selected row & hide the disclosure chevrons in all the other. While doing that, you can set the selection style to 'none'
For my iPhone app, I have an editable (for delete) table view. I'd like to be able to detect that the user has clicked the "Edit" button. See this image: http://grab.by/It0
From the docs, it looked like if I implemented :
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
then I could detect it (although from the name of the method, I wouldn't think that). This proved not to work.
Any ideas on detecting this? The reason I want to is I want to hook up a "Delete all" button in the upper left hand corner when in delete mode.
thanks
It is probably not working as you expect because willBeginEditingRowAtIndexPath: is called before the editing starts.
If you want to check while in another method you need the editing property:
#property(nonatomic, getter=isEditing) BOOL editing
If you want to do something when the 'Edit' button is pressed you need to implement the setEditing method:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
Which you'll find in UIViewController. (Well, that's the most likely place; there are others.)
Swift
Use below code accordingly:
open var isEditing: Bool // default is NO. setting is not animated.
open func setEditing(_ editing: Bool, animated: Bool)
When subclassing a tableviewcontroller (what most people are going to be doing most of the time since you have to override it's delegate methods just to put data into it...) you can just override the setEditing:animated: method to grab editing state changes.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
NSLog(#"Editing %i", editing);
[super setEditing:editing animated:animated];
}
That passes the state change along to the super class, but lets you jump in the middle and detect the change, or alter it if you wanted...
The setEditing:animated: examples didn't work for me (on iOS 6.1) to detect the state changes that occur when you enter and exit delete confirmation mode. It seems that setEditing:animated: is only called once, when the table view goes into edit mode, but not on state changes of the cells. After some debugger fun, I arrived at a method to detect the cell state change.
My use case is different from yours. I just wanted to hide the label when the delete button is showing so that the other cell content doesn't overlap it when the Delete button slides in. (I'm using UITableViewCellStyleValue2, the one with the blue label on the left and black label on the right.)
(In your UITableViewCell subclass)
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if (state & UITableViewCellStateShowingDeleteConfirmationMask) {
// showing delete button
[self.textLabel setAlpha:0.0f]; // <-- I just wanted to hide the label
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
if (!(state & UITableViewCellStateShowingDeleteConfirmationMask)) {
// not showing delete button
[self.textLabel setAlpha:1.0f]; // <-- show the label
}
}
Kendall 's answer works. I did it in following way.
// 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.
NSLog(#"Can edit %d", tableView.editing);
if (tableView.editing == 1) {
[self.editButtonItem setTitle:EDIT_BUTTON_TITLE];
}else {
[self.editButtonItem setTitle:DONE_BUTTON_TITLE];
}
return YES;
}
That method tells you when a user is editing a Cell, not put the table into editing mode. There is a method called when editing mode is entered, to ask each cell if it can be edited:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
I don't think overriding setEditing:animated: makes sense, since you would have to subclass UITableView which is extra work and a class you need for no other reason, not to mention it would have to communicate the fact that editing had been turned on back to the controller.
One other option is to simply add the Edit button yourself - it's a built in UIBarButtonSystemItem, you can add it and then have it call your own method in which you do something specific then call setEditing:animated: on the UITableView itself.
The idea behind editing is that when editing is enabled, each cell is told to go to edit mode, and as asked if there are any specific editing controls that should be applied. So in theory there's no need to detect entry into editing mode beyond changing the appearance of cells. What are you trying to do when editing mode is entered?
I have a RootViewController class which is inherited from UITableViewController.
When a cell is deselected by the user I want to enable/disable certain buttons on the toolbar.
How do I trap the deselect event?
-(void)tableView:(UITableView *)tableView deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
{
if(indexPath.row <= rowNumber)
{
[viewButtton setEnabled:NO];
[editButtton setEnabled:NO];
}
}
I tried using this method but it doesn't seem to execute at all. Any ideas how cam this be done?
I do not think there is a deselectRowAtIndexPath event, there is a method that you can call to deselect the indexPath, but looking at the SDK I do not see an event for this in the UITableViewDelegate: http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html.
Could you enable/disable certain buttons on the toolbar during the didSelectRowAtIndexPath: event?
-Rog
This is in the current beta SDK only which means it could be buggy / changed / unsupported...
I did noticed that your method declaration doesn't match the SDK (at least, the version I have).
Try removing animated:(BOOL)animated; I don't think it's applicable here.
See line ~345 in UITableView.h, and/or right click on didDeselectRowAtIndexPath and "Jump to Definition", where you'll probably find how the delegate method should be defined.
That said, if your goal is simply to "enable/disable certain buttons when a cell is selected",
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
should work just fine. This will occur after they select the cell and before it's deselected. 'deselect' has to do more with animation than user interaction. The only reason I can think you would want to use deselect is maybe the aesthetic value of ensuring your event only occurs after the select cell is no no longer highlighted.