UITableView --> Editing mode - ios

I have an IBAction with a UIButton that enables the edit mode. I'd like to hit the same UIButton and cancel the edit mode. If I use an if-else statement, what do I check for : if(editeModeEnabled)//turn it off, else turn it on ... so I can use the same UIButton for both on and off.
Thanks much.

You can check for the tableView.editing == YES
eg:
if(self.tableView.editing)
//Turn editing off/save changes
else
{
//Turn editing on
[self.tableView setEditing:YES animated:YES];
}

If the button is a bar button item, then the easiest way to toggle the edit button is to set the bar button item to the pre-configured editButtonItem.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
This special button automatically toggles between "Edit" and "Done"; it also puts the table view in editing mode.

Related

Hide Keyboard on clear click in UISearchBar and not backspace to empty text

I cant seem to find this answer for the manually clearing the UISearchBar with a backspace, only with a cancel button click. The code below hides the keyboard when the clear button is clicked, but so does the backspace to an empty UISearchBar. Id like to leave the keyboard open in that scenario since someone might be typing something else.
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
[self filterData: text];
if(text.length == 0)
{
[searchBar performSelector:#selector(resignFirstResponder) withObject:nil afterDelay:.1];
}
}
Your code includes if(text.length == 0) and that means that when the size of the input becomes zero, keyboard is dismissed. However the actual piece should be as follows:
- (BOOL) searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[searchBar resignFirstResponder];
return YES;
}
My best try on such an issue is to do as suggested here BUT IT DOES NOT WORK WHEN YOU CLICK CLEAR BUTTON :( but I thought it might help you though:
https://stackoverflow.com/a/16957073/1465756
Add a tap gesture on your whole view:
- (void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
and dismissKeyboard when the view is tapped:
- (void) dismissKeyboard
{
[self.searchBar resignFirstResponder];
}
I understand you want to dismiss the keyboard when the user hits Cancel, and you also want to dismiss when the user hits the clear (x) button.
You do not need to implement searchBar:textDidChange:.
To detect cancellation, implement searchBarCancelButtonClicked:. Here you can trigger resignFirstResponder.
To detect clear, adopt UITextFieldDelegate and implement textFieldShouldClear:. This will be called after the user taps clear, but before the clear occurs. Return YES to allow the clear to occur. You may dismiss the keyboard before returning.

one Button With Multiple Actions Using StoryBoard in ios

I have three buttons with different actions.Now I don't want to create three IBAction to my buttons.In single IBAction Method can i write the actions for those three buttons.
I am new to Xcode,Can anyone help me to do this...
Thanks in Advance....
try like this
in . h file
#property (strong, nonatomic) IBOutlet UIButton *yourbutton;
in .m
#synthesize yourbutton;
- (IBAction)yourClicked:(id)sender {
UIButton *resultebutton= (UIButton*)sender;
NSString *buttontitle=resultButton.currentTitle;
if ([buttontitle isEqual:#"firstBtitle"]) {
// perform your 1st button action
//call your method
}
else if ([buttontitle isEqual:#"secondBtitle"]) {
// perform your 2nd button action
}
else if ([buttontitle isEqual:#"thirdBtitle"]) {
// perform your 3rd button action
}
}
Assign tag for buttons, and in IBAction method, check Button tag and do action, according to tag of button.
Please correct me, if I get you wrong:
You have three buttons and you want them to trigger the same IBAction. The IBAction itself decides what to do based on which button calls it.
This sounds to me like a perfect example for the "sender" parameter.
Create something like this:
- (IBAction)doSomeAction:(id)sender
{
if ([sender isEqual:self.buttonOne]) {
NSLog(#"ButtonOne");
} else if ([sender isEqual:self.buttonTwo]) {
NSLog(#"ButtonTwo");
} else if ([sender isEqual:self.buttonThree]) {
NSLog(#"ButtonThree");
}
}
With the sender you can identify the button, which calls this method. This way, you can avoid handle tags which can be very annoying to use.
Make sure you connect all three buttons to this action - take a look at the connections inspector. This is very important and a common source for errors. If you remove any connection to an outlet or an IBAction, also check, if this connection ist remove in the Storyboard-object.
If everything is in place just compare the sender with the outlets of the buttons.
Step 1:
Assign your all three buttons different tag in storyboard/XIB,
For ex. firstButton with tag=1, secondButton with tag=2 and thirdButton with tag=3
Step 2:
Define your method like this and bind all your buttons with this method
- (IBAction)buttonAction:(UIButton *)sender
{
if (sender.tag==1) {
NSLog(#"First Button");
} else if (sender.tag==2) {
NSLog(#"Second Button");
} else if (sender.tag==3) {
NSLog(#"Third Button");
}
}
And your work is done.

iOS: setting buttons pressed state

I am trying to find the best approach to doing this. I have 5 custom buttons on a view controller and I am trying to have the button stay highlighted if it is clicked. I know how to do this but I am trying to only allow 1 button to be highlighted at a time. So if a user clicks a button and highlights it, but clicks another, then the most recent button clicked will stay highlighted and the previous will unhighlight. What would be the best way to accomplish this?
You should keep a reference to all your buttons (for example, if you use IB, have links in your code like #property (nonatomic, strong) IBOutlet UIButton *button1; for all your buttons).
Then link all your buttons to the same method for a press on the button. I'll call it buttonPressed.
Impement it like this :
- (IBAction)buttonPressed:(id)sender {
UIButton *buttonPressed = (UIButton*)sender;
NSArray *buttons = [NSArray arrayWithObjects:_button1, _button2, _button3, nil];
bool buttonIsHighlighted = NO;
// Check if a button is already highlighted
for (UIButton *button in buttons) {
if (button.highlighted) {
buttonIsHighlighted = YES;
}
}
// If a button is highlighted, un-highlight all except the one pressed
// If no button is highlighted, just highlight the right one
if (buttonIsHighlighted) {
for (UIButton *button in buttons) {
if (buttonPressed == button) {
buttonIsHighlighted = YES;
} else {
button.highlighted = NO;
}
}
} else {
buttonPressed.highlighted = YES;
}
}
I can't test this code but I'm pretty sure it should work. Let me know if something's wrong.
Solution 1:
Put your buttons in an NSArray and when user clicks on a button check if another is highlighted. If YES, unhighlight it and highlight the one was pressed. If NO, highlight directly the one pressed.
Solution 2:
You can save the highlighted button in a global variable declared in #interface or in a #property. When users click the new one unhighlight the previous.

Two actions for one UIBarButtonItem?

I have an edit button, that I obtained through self.editButtonItem and I have set it as self.navigationItem.leftBarButtonItem, such that when it is pressed, a UITableView begins editing and it turns into a "Done" button. When pressed again the view stops editing and the button returns to its normal state.
I would also like an "add" button to turn into a "Clear" button with a different action linked to it when the edit button is pressed.
(Much like in the iPhone "Phone" app's favourites tab, just that the plus button turns into a clear button when the Edit button is pressed).
I would really like to obtain the edit action and style etc in this way (self.editButtonItem), but I would also like to have an extra selector linked to the edit button.
How should I go about doing this? I have tried to create a category for UIBarButtonItem, but I don't really know what I should do with that.
Thanks.
To create a button whose title can change, you can do the following:
Define an ivar for the button:
UIBarButtonItem *_btnAddClear;
In viewDidLoad:
_btnAddClear = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonItemStyleBordered target:self action:#selector(addClearAction:)];
_btnAddClear.possibleTitles = [NSSet setWithObjects:#"Add", #"Clear", nil];
Since you want this button's title to change when the Edit/Done button is tapped, you can add code like the following:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
_btnAddClear.title = editing ? #"Clear" : #"All";
}
And lastly, the button handler:
- (void)addClearAction:(UIBarButtonItem *)button {
if (self.editing) {
// perform "clear" action
} else {
// perform "add" action
}
}
Give tag of UIBarButton such like 101;
and in BarButton Method write following
-(void)barButtonMethod
{
UIBarButtonItem * myButton = (UIBarButtonItem *) sender;
if(sender.tag == 101)
{
yourBtn.tag = 102;
// Write Your first action method such like
[self ActionMethod1];
}
else
{
yourBtn.tag = 101;
// Write Your second action method such like
[self ActionMethod2];
}
}
You don't really need a new action for the editButtonItem.
There is a property that tracks if the UIViewController is in editing state.
#property(nonatomic, getter=isEditing) BOOL editing
In order to do what you want, you can implement the following method in your UITableViewController:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated]
//Do your thing
}

iOS - Prompt When Navigating From View

I have a UINavigationController inside a UITabBarController. The navigationcontroller has a UITableView and a form for editing items. The problem is that if a tab is tapped during editing, the form is just cleared and the user is dumped back to the UITableView.
Is there a way I can add a prompt to confirm navigation away from the edit view?
First, declare a BOOL in your .h to store the editing state. Also declare a temporary variable we will use later for storing the selected row.
BOOL isEditing;
NSUInteger selectedRow;
In your viewDidLoad, initialize the boolean to NO
- (void)viewDidLoad {
// initialization
isEditing = NO;
[super viewDidLoad];
}
You can then conform your view controller to UITextFieldDelegate and UIAlertViewDelegate. The text field delegate allows the controller to receive callbacks when editing ends and begins for the text fields and the alert view delegate allow it to receive callbacks when an alert view is dismissed.
#interface MyController : UIViewController <UITextFieldDelegate, UIAlertViewDelegate>
You then also need to set all the text field's delegates to be assigned to the controller. So in your cellForRowAtIndexPath when you add the text fields, just add this:
textField.delegate = self;
Once you have this, you are all set up to receive callbacks from the text field - so now implement the following two methods like so:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
isEditing = YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
isEditing = NO;
}
Now the key here is to make a separate method for pushing the next view, so just do something like this (like you would normally when the table view row is selected):
- (void)showNextView {
// in this method create the child view controller and push it
// like you would normally when a cell is selected
// to get the selected row, use the `selectedRow` variable
// we declared earlier.
}
You now need to implement the table view callback when the user selects a row - in this method we test if they are editing and show them a prompt if they are. If they aren't, we go to the next view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedRow = [indexPath row];
if (isEditing) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Continue Editing?"
message:#"Continue Editing or discard edits"
delegate:self
cancelButtonTitle:#"Discard"
otherButtonTitles:#"Continue"];
[alert show];
[alert release];
return;
}
[self showNextView];
}
Finally, we need to implement the alert view delegate callback for when the alert view is dismissed:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) return; // stay editing
[self showNextView];
}
Hope that all makes sense and is helpful to you!
Since you are using a UINavigationController, if you are pushing this "form" onto the stack you could set
#property(nonatomic) BOOL hidesBottomBarWhenPushed
That way the tab bar would be hidden until they are done with the form.
I solved this eventually by using a custom UIBarButtonItem which looks like a back arrow.

Resources