How to use commitEditingStyle? (UITableViewCell-UITableView) - ios4

I am looking at various possible ways to implement delete-edit-copy feature on the UITableViewCell elements of a UITableView.
The one I am trying now is based on the usage of the following methods:
[tableView setEditing:YES animated:YES];
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath;
I can see some advantages to use this approach, but there is one problem:
When I try it, I can make the red "Delete" button appear and work, but that is all.
Is there a mechanism by which I could also have "edit" and "copy" buttons ?
Or is it just not possible?
Thanks for any helpful information.

EDIT
I just understood that you are referring to the cell, not the TableView. For the cell, the following styles are provided:
UITableViewCellEditingStyleDelete:
The cell has the delete editing control; this control is a red circle enclosing a minus sign.
UITableViewCellEditingStyleInsert:
The cell has the insert editing control; this control is a green circle enclosing a plus sign. You may use it for "copy".
UITableViewCellEditingStyleNone: The cell has no editing control.
Further styles you have to implement on your own.
Original Answer
You can use the editButtonItem method of UIViewController. It returns a bar button item that toggles its title and associated state between "Edit" and "Done" (but not "Copy"). The default button action already invokes the setEditing:animated: method.
If you want another state, your have to create your own BarButtonItem.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[DummyData removeObjectAtIndex:indexPath.row];
[_tableView reloadData];
}
}
Use this code. Hope it helps and please do the same with UITableViewCellEditingStyleInsert

Related

Java FX 2 Cell Editing, Focus and Text Selection

I am testing JavaFX 2.1 and trying to get editable table views to behave the way I would like them to.
I'm using the example from the JavaFX 2 documentation as a base :http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
The example has 2 problems:
The user is forced to click on a cell 3 times in order to edit it, once to select the row, once to select the cell and make it editable and a further click to focus the TextField
The changes are only committed when the enter key is pressed, if the mouse is clicked outside of the cell, then the data entered in the cell is lost.
On the other hand, one feature that does work correctly, is that I can select text, and re-position the caret within the TextField using the mouse as many times as I like.
There are 2 questions here relating to both of these issues individually:
Java FX 2 Table Cell Editing and Focus
and
javafx 2.1 Updating TableView
When the answer to first question is applied on it's own, I only have to click once to edit the cell (after the row has been selected) and I can still select text and move the caret.
When the answer to the second question is applied on it's own, the edit is committed without the enter key being pressed, but I can only re-position the caret or select text once, if I try a second time, then the edit is committed.
When I apply both answers together, focus is applied successfully and edits are committed when the mouse is clicked away, but I lose the ability to re-position the caret or select text entirely. Any mouse click within the cell commits the edit.
My question is how can I fix the original 2 issues without losing the ability to position the caret and select text?
Try jkaufmann's sample app in his answer to his own question TableView - Better Editing through Binding? His binding solution and implementation of TableView editing semantics seems to adequately address all concerns you raise in your question.
You need to modify the GUI component at the correct time in the spirit of the JavaFX framework. i.e. in the controls layoutChildren method. You need to override the layoutChildren method of the custom TableCell and set the cursor position then e.g.
TextField textField = new TextField() {
private boolean first = true;
#Override protected void layoutChildren() {
super.layoutChildren();
// Set cursor caret at end of text (and clear highlighting)
if (first) {
this.end();
first = false;
}
}
};
I also note that Java 1.8.0_241 also contains this problem in the TextFieldTableCell implementation. Worse TextField is completely private to the TextFieldTableCell implementation, so in order to work around that I chose to copy the source of javax.scene.table.cell.TextFieldTableCell and javax.scene.table.cell.CellUtils. TextField is instantiated in CellUtils, so you can fix the cursor positioning there. e.g.
static <T> TextField createTextField(final Cell<T> cell, final StringConverter<T> converter) {
final TextField textField = new TextField(getItemText(cell, converter)) {
private boolean first = true;
#Override protected void layoutChildren() {
super.layoutChildren();
// Set cursor caret at end of text (and clear highlighting)
if (first) {
this.end();
first = false;
}
};
...
...
}

MonoTouch.Dialog: Dismissing keyboard by touching anywhere in DialogViewController

NOTE: There are two similar SO questions (1) (2), but neither of them provides an answer.
TL;DR: How can one dismiss the keyboard in a MonoTouch.Dialog by letting the user touch any empty space in the view?
I'm writing an app using MonoTouch.Dialog and a UITabBarController. One of my tabs is "Settings"...
When the user starts typing, the keyboard obstructs the tabbar...
Using MonoTouch.Dialog, the only way to dismiss the keyboard is to go to the last field and press the "return" key. Considering the fact that the user cannot press any tab until the keyboard is gone, I would like a better way to do it. Namely, to dismiss if the user taps anywhere else on the screen.
Without MonoTouch.Dialog, it's a snap: simply override TouchesBegan and call EndEditing. But this doesn't work with MT.D. I've tried subclassing DialogViewController and overriding TouchesBegan there, but it doesn't work. I'm currently at a loss.
Or, I wonder, would I be better off ditching the tabbar so I can use a UINavigationController with a "Back" button on top, which won't be hidden by the keyboard?
I suggest you use a tap gesture recognizer that will not cause interference with the TableView event handlers:
var tap = new UITapGestureRecognizer ();
tap.AddTarget (() => dvc.View.EndEditing (true));
dvc.View.AddGestureRecognizer (tap);
tap.CancelsTouchesInView = false;
You missed my question about it also: Can the keyboard be dismissed by touching outside of the cell in MonoTouch.Dialog?
:-)
This is my #1 feature request for MonoTouch.Dialog.
To answer your question: No. It is not possible. I have searched and asked around and have not found any answers.
I assume because it is just a sectioned (grouped) table and if it wasn't sectioned, there wouldn't be any spot to click. However, that is just my speculation.
I wish that miguel or someone that works on monotouch would answer this and say if it is even possible. Possibly a future enhancement?
I figured out a workaround that satisfies me well enough, so I'm answering my own question.
// I already had this code to set up the dialog view controller.
var bc = new BindingContext (this, settings, "Settings");
var dvc = new DialogViewController (bc.Root, false);
// **** ADD THIS ****
dvc.TableView.DraggingStarted += (sender, e) => {
dvc.View.EndEditing (true);
};
This will dismiss the keyboard whenever the user drags the view a little bit. There's no touch event I could find associated with the tableview, so this is the next best thing. I'd welcome any other ideas. Cheers!
One workaround to use the dragging gesture instead of the tap as proposed (that do not interfere with the table view gestures) is to override MonoTouch.Dialog.DialogViewController.SizingSource (or MonoTouch.Dialog.DialogViewController.Source if you don't want uneven rows) and give it to the DialogViewController. I don't know if it is very clean or safe.
public class CustomTableViewSource : MonoTouch.Dialog.DialogViewController.SizingSource
{
public CustomTableViewSource(MonoTouch.Dialog.DialogViewController dvc) : base(dvc)
{
}
public override void DraggingStarted(UIScrollView scrollView)
{
base.DraggingStarted(scrollView);
if (scrollView != null)
{
scrollView.EndEditing(true);
}
}
}

Detect if UIViewController is running inside an existing UINavigationController

I'm creating a generic reusable UIViewController component that people can add to their applications. It requires a navigation bar at the top where it will add some buttons.
I can easily create a navigationBar and add the buttons, but if the developer using my component is adding the view as part of an existing navigation structure, they might end up with 2 navigation bars.
In other words, if my view is loaded with:
[self.navigationController pushViewController:controller animated:YES];
then it should not add a navigationbar and use what's already there. If the view is loaded with:
[self presentModalViewController:controller animated:YES];
then it should add its own navbar.
Without requiring the developer that uses my controller to do something like a useNavBar:YES, is there a way to do this automatically?
Something like a [self isRunningInsideANavigationController] or [self hasNavigationBar] would do.
You could use self.navigationController for that purpose. It will return nil or the navigationController.

Core Data: delay calling endUpdates till viewWillAppear

I have a Core Data app with a tab-bar controller that displays 2 view controllers. If I add something in the first tab's view controller, it should display in the 2nd tab's VC. Both VCs are based off a NSFetchedResultsController which is based off the same entity; the only difference is that one has a predicate and the 2nd VC doesn't.
This works fine for the normal template, and when data is added from the 1st VC, it gets updated instantly in the 2nd tab using controllerWillChangeContent and controllerDidChangeContent. The problem is that if the user adds or deletes any rows in the 1st VC, when the user comes to the 2nd tab they don't see the rows animatedly inserted or deleted... everything's already there.
What I would like to do, in the 2nd tab's VC, is delay calling the [self.tableView endUpdates] (which causes the animated inserting/deleting of rows in the table) till the user actually goes to that tab, in that VC's viewWillAppear. I've tried this, but doesn't seem to work:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
tableviewUpdates = TRUE;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (tableviewUpdates) {
tableviewUpdates = FALSE;
[self.tableView endUpdates];
}
}
This works if adding one row at a time and then switching to the 2nd tab, but not if I add multiple rows in the 1st tab and then switch.
Any help would be appreciated.
You're working against the purpose of the NSFetchedResultsController which is to make updating the tableview automatic and effortless.
I'm pretty sure, however, that if you override all the FRC delegate methods you can block all the automatic updates.
You might want to rethink this design. Are users really going to expect to see changes in one view reenacted in a second? Will they understand they are watching a rewind of the previous changes or will they intuitively think that the app is doing something to their data on its own?
The standard UI grammar teaches users to expect that one change animates once and then subsequently just shows up in a standard display. I would suggest you test this design with naive users carefully before deploying such a non-standard interface.

Navigation bar items disappear from navigation bar

I have been struggling for some time with the strange behavior of navigation bar items. I have segmented control on the navigation bar (take a look at the image below)
where List button pushes table view controller with UISearchDisplayController. To show table view controller I use the code as it follows:
if (uiSegmentedControl.selectedSegmentIndex == 1 )
{
DetailsTableVewController* detailsViewController = [[DetailsTableVewController alloc]
initWithList:list];
[self.navigationController pushViewController:detailsViewController animated:YES];
[detailsViewController release];
}
Then to return back I use the following code:
[self.navigationController popViewControllerAnimated:YES];
Although I use the code above to go back to the previous controller when UISearchDisplayController is either active or inactive I have different behavior of the navigation bar items. When UISearchDisplayController is active ALL items disappear from the navigation bar
Does anybody know why it happens?
Thanks in advance.
Moved all navbar initialization code from viewDidLoad to viewWillAppear in controller and it solved the problem

Resources