I have the UISearchDisplayController page view as follows (original state)
After clicking on the searchbar and typing some search term, I get a list of results in the table
After clicking on an entry in the table, a new viewController is displayed on top of the stack
My intention is that on the click of the cancel button (on top left), the root view will display the original state of the searchDisplay controller
This is what I have tried
In my cancel method (triggered when I click on the top left hand cancel button)
- (void)cancel
{
[self dismissViewControllerAnimated:YES completion:NULL];
[self searchBarCancelButtonClicked:self.searchDisplayController.searchBar];
}
And in the searchbar delegate method I did this
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
self.searchBar.showsCancelButton = NO;
[self.searchBar resignFirstResponder];
self.searchBar.text = #"";
searchDisplayController.searchResultsTableView.hidden = YES;
[self searchDisplayControllerWillEndSearch:self.searchDisplayController];
}
All I manage to achieve after clicking on the cancel button is this
The original tableview seems to be missing (appears only if I click on the page)
How can I modify my methods to revert the search to its' original state?
Try [searchDisplayController setActive:NO animated:NO]
This should hide the search table.
Related
I have looked around but haven't found a satisfying answer. My problem is that whenever I call popToRootViewControllerAnimated:(BOOL) it is not doing anything. When I NSLog it, it logs (null).
Let me back up a bit here. I have a table view controller that has a list of things, at the navigation bar up top there is an option to add and that takes me to a new view controller with a segue "Present as PopOver" which gets rid of the principal or main navigation bar. So I made one manually and added 2 bar button items "Cancel" and "Add". When "Cancel" is tapped, it should take the user back to the table view controller and discard changes, when "Add" button is tapped, it should also take user back to the previous table view controller with the changes. But it's not doing anything.
Here is my code.
- (IBAction)cancelButton:(UIBarButtonItem *)sender {
UINavigationController * navigationController = self.navigationController;
NSLog(#"%#", navigationController);
NSLog(#"cancel tapped though");
ListingTableViewController *rootController = [[ListingTableViewController alloc] init];
[navigationController popToRootViewControllerAnimated:NO];
[navigationController pushViewController:rootController animated:YES];
}
As far as the segue, this view controller is not connected to anything, or should I connect it? This is a noobish question indeed. Here is my xcode screenshot.
Check this link for the screenshot of the storyboard
http://i.stack.imgur.com/lqnCF.png
You must call
- (IBAction)cancelButton:(UIBarButtonItem *)sender {
NSLog(#"cancel tapped though");
[self dismissViewControllerAnimated:YES completion:nil];
}
instead of popToRootViewControllerAnimated because your VC presented and not pushed!
When presenting a view, you are not pushing it in your navigation controller, but having it presented. To dismiss it, try using [self.presentingViewController dismissViewControllerAnimated:NO completion:nil].
My app has an 'inspector' panel defined by a .xib file and a custom window controller class: AdjustmentsWindow.xib and AdjustmentsWindowController.m.
I want to have a Window -> Show Adjustments menu item in the application's main menu bar, that when selected will show the adjustments window. I dropped and NSObject instance into the xib containing the main menu, and changed its class to "AdjustmentsWindowController". I also hooked the menu item's action to the controller's -showWindow: method. So far so good: The window controller is instanced on app launch, and when you select the menu item it shows its window.
But I want the same menu item to double as 'Hide Adjustments' when the window is already visible (effectively toggling visibility). So here is what I did:
AdjustmentsWindowController.m:
- (void) windowDidLoad
{
[super windowDidLoad];
[[self window] setDelegate:self];
}
- (void) showWindow:(id)sender
{
// (Sent by 'original' menu item or 'restored' menu item)
[super showWindow:sender];
// Modify menu item:
NSMenuItem* item = (NSMenuItem*) sender;
[item setTitle:#"Hide Adjustments"];
[item setAction:#selector(hideWindow:)];
}
- (void) hideWindow:(id) sender
{
// (Sent by 'modified' menu item)
NSMenuItem* item = (NSMenuItem*) sender;
// Modify back to original state:
[item setTitle:#"Show Adjustments"];
[item setAction:#selector(showWindow:)];
[self close];
}
- (void) windowWillClose:(NSNotification *)notification
{
// (Sent when user manually closes window)
NSMenu* menu = [[NSApplication sharedApplication] mainMenu];
// Find menu item and restore to its original state
NSMenuItem* windowItem = [menu itemWithTitle:#"Window"];
if ([windowItem hasSubmenu]) {
NSMenu* submenu = [windowItem submenu];
NSMenuItem* item = [submenu itemWithTitle:#"Hide Adjustments"];
[item setTitle:#"Show Adjustments"];
[item setAction:#selector(showWindow:)];
}
}
My question is, is this the right/smartest/most elegant way to achieve this? I mean, this is pretty standard behaviour in cocoa apps (cf. Numbers' "Inspector"), how does everyone else do it?
One way to improve it would be to avoid the code duplication of restoring the menu item to its original title/action. Also, ideally I would replace the title strings with calls to NSLocalizedString(). But perhaps there's a more elegant, standard approach that I don't know...
Application Menu and Pop-up List Programming Topics said
validateMenuItem: is also a good place to toggle titles or set state on menu items to make sure they're always correct.
I want to click the back button in the navigationBar programmatically in my second view.
It's call it this way:
Archiv *archiv = [[Archiv alloc] initWithNibName:#"Archiv" bundle:nil];
archiv.title = [NSString stringWithFormat:#"Archiv %#", [sender titleForState:UIControlStateNormal]];
[self.navigationController pushViewController:archiv animated:YES];
And now i'm in the Archiv.m and after a specific event i want to get back to the first controller (without clicking the back button) - instead i want to perform the click programmatically.
Is it possible for this case?
Helpful would be to know which method is called if i click on this button, so don't even have to perform the click.
yes you can
this will take you to your first view controller
[self.navigationController popToRootViewControllerAnimated:YES];
I have a Navigaton Controller displaying a TableView and a toolbar with a button.
If the user presses the button a modal view is displayed with several buttons. On pressing one of those buttons a new set of data is loaded and the tableView is reloaded.
Under a certain condition when a new set of data is reloaded I need to show a modal view to alert the user of some situation.
This is the code I original write to show the alert to the user:
- (void) selectEventosListMVCButtonPressed:(NSInteger)button
{
switch (button) {
.
.
.
.
case 3:
// eventos favoritos
// Load Favourites Events
// This is the new data to load
if (!self.eventosFavourites) {
[self loadEventos:kURLEventosCopyFavourites];
}
// Empty the container
[self.eventosListsContainer removeAllObjects];
// Load Favourites Eventos
[self.eventosListsContainer addObject:self.eventosFavourites];
// Reload the view
[self.tableView reloadData];
// Load Expired Events
// If there are some eventosExpired then show alert to user
if (!self.eventosExpired) {
[self loadEventos:kURLEventosCopyExpired];
}
if (self.eventosExpired) {
// There are expired eventes
// Load a modal view to inform the user
ExpiredEventosMVC *expiredView = [[ExpiredEventosMVC alloc] initWithNibName:#"ExpiredEventosMVC" bundle:0];
expiredView.delegate = self;
expiredView.eventos = self.eventosExpired;
[self presentModalViewController:expiredView animated:YES];
[expiredView release];
}
break;
}
[self.modalViewController dismissModalViewControllerAnimated:YES];
[self.modalViewController release];
}
But the modal view never shows.
For this to work I should wait after the ExpiredEventosMVC modal view is displayed to the user click the OK button in that view to dismiss it and continue the flow, but how can I do this?
You're presenting the modal controller with this line of code:
[self presentModalViewController:expiredView animated:YES];
And then immediately dismissing it two lines later:
[self.modalViewController dismissModalViewControllerAnimated:YES];
Your code should dismiss the controller after the user has pressed one of its buttons, not before. To do this, configure the buttons to send action messages to your controller, and call dismissModalViewControllerAnimated: from there.
By the way, naming the variable in which you're storing a view controller expiredView is likely to lead to confusion. Consider expiredController, expiredViewController, or expiredVC. (But not expiredMVC -- that's not such a good idea either. MVC is an acronym for Model-View-Controller -- a design pattern, not a class.)
I know I can set showsCancelButton to NO for a UISearchBar ... until you tap the search bar text field, and then the cancel button appears anyway! (At least it does for me.)
Is there a way to show the "X" in a circle within the UISearchBar text field vs. having that separate Cancel button show up adjacent to it? Note that this button only appears for me when search mode is active, and this is regardless of the setting for showsCancelButton.
try this
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
// only show the status bar's cancel button while in edit mode
mySearchBar.showsCancelButton = NO;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
mySearchBar.showsCancelButton = NO;
}
when using this cancel button will not shown.
for (UIView *searchBarSubview in [searchBar subviews]) {
if ([searchBarSubview conformsToProtocol:#protocol(UITextInputTraits)]) {
[(UITextField *)searchBarSubview setClearsOnBeginEditing:YES];
}
}
to enable the cancelButton try searchBar.showsCancelButton = YES;
Try the above lines of code.
if you use interface builder it is ery easy to show.it is there by default.i have used search bar in my app and the searchbartextfield has an "X" to clear the textfield
It might be that the "X" is only intended to clear the search field and not to cancel the search, and so the Cancel button must remain once a search is in play, regardless of showsCancelButton.