When does searchDisplayController delegate methods get called? - iphone

I set up my searchDisplayController and searchBar like so:
UISearchBar *aSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 150, 44)];
self.reportSearchBar = aSearchBar;
_reportSearchBar.tintColor = DARKGRAY_COLOR;
_reportSearchBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
_reportSearchBar.delegate = self;
[aSearchBar release];
UISearchDisplayController *searchDisplayCtlr = [[UISearchDisplayController alloc] initWithSearchBar:self.reportSearchBar contentsController:self];
self.reportSearchDisplayController = searchDisplayCtlr;
self.reportSearchDisplayController.searchResultsDataSource = self;
self.reportSearchDisplayController.searchResultsDelegate = self;
[searchDisplayCtlr release];
UIBarButtonItem *searchBBI = [[UIBarButtonItem alloc] initWithCustomView:_reportSearchBar];
self.reportSearchBBI = searchBBI;
[searchBBI release];
[self.navigationItem setRightBarButtonItem:_reportSearchBBI animated:NO];
I checked if my ViewController conforms to the class just in case:
if ([self conformsToProtocol:#protocol(UISearchDisplayDelegate)]) {
NSLog(#"conform to search display");
}
My ViewController .h file has:
<UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate>
however, I set a break point at
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString];
return YES;
}
And it never reaches there. I implement one of the UISearBarDelegate methods and it does get to that method. When I run Apple's example code TableSearch, the searchDisplayController delegate method copied above does get run. So for me, I try to put in text into the search bar and my app crashes since the filtered list has no objects in it since the searchDisplayController delegate never gets called.
Thoughts? Thanks!

I just see in the apple reference:
searchController = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar contentsController:self];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
I dont see the searchController.delegate = self in your code, isn't that nessesary?
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UISearchDisplayController_Class/Reference/Reference.html

Make sure you create an iVar for the UISearchDisplayController in your header file.
If you create an UISearchDisplayController using:
UISearchDisplayController* searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
it will get released by ARC, it will not call any delegate methods and when you'll call self.searchDisplayController (the UIViewController's property) it will be nil.
So, the fix is:
In your header (.h) file:
#interface MenuViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate> {
UISearchDisplayController* searchDisplayController;
UISearchBar *searchField;
UITableView* tableView;
NSArray* searchResults;
}
and in the implementation (.m) file:
searchField = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 49)];
searchField.delegate = self;
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;
tableView.tableHeaderView = searchField;
tableView.contentOffset = CGPointMake(0, searchField.frame.size.height);
When implemented like that, you can call both self.searchDisplayController and searchDisplayController in the rest of your code.

Related

Why is UISearchBar not shown correctly?

In order to understand how UISearchDisplayController works i've written the following code in viewDidLoad method:
UISearchBar * searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40.0f)] autorelease];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
_searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
_searchController.delegate = self;
_searchController.searchResultsDataSource = self;
_searchController.searchResultsDelegate = self;
[_searchController setActive:YES animated:YES];
[_searchController.searchBar becomeFirstResponder];
But when i run my code the UISearchBar doesn't being shown as you can see in the image.
You create UISearchBarcontroller its good but not added in uiviewcontroller. So You add UISearchBarcontroller in uiviewcontroller.
coding:
[self.view addsubview:_searchController];

Delegate Methods Not Firing on Search Results Table

All,
I have a UITableView w/detail, with a Search bar, created from code. Works fine on selected items except it doesn't work when an item is clicked from the search results; no delegate methods fire. Never seen this type of behavior before so I don't know where the issue lies.
I get the same behavior with standard table cells as well as custom table cells.
Appreciate any guidance on this and thanks.
Just Hangs Here
//ViewController.h
#interface SongsViewController : UITableViewController <UISearchBarDelegate,UISearchDisplayDelegate>
{
NSMutableArray *searchData;
UISearchBar *searchBar;
UISearchDisplayController *searchDisplayController;
UITableViewCell *customSongCell;
}
//ViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 88)];
[searchBar setShowsScopeBar:YES];
[searchBar setScopeButtonTitles:[[NSArray alloc] initWithObjects:#"Title",#"Style", nil]];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableView.tableHeaderView = searchBar;
//Load custom table cell
UINib *songCellNib = [UINib nibWithNibName:#"SongItem" bundle:nil];
//Register this nib, which contains the cell
[[self tableView] registerNib:songCellNib forCellReuseIdentifier:#"SongItemCell"];
// create a filtered list that will contain products for the search results table.
SongStore *ps = [SongStore defaultStore];
NSArray *songObjects = [ps allSongs];
self.filteredListContent = [NSMutableArray arrayWithCapacity: [songObjects count]];
self.masterSongArr = [[NSMutableArray alloc] initWithArray:[ps allSongs]];
[self refreshData];
[self.tableView reloadData];
self.tableView.scrollEnabled = YES;
}
I fixed this issue. I forgot to set this searchDisplayController delegates:
[searchDisplayController setSearchResultsDelegate:self];
So make sure you set All of these:
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
[searchDisplayController setSearchResultsDelegate:self];

NavigationController not showing on UIViewController presenting modally

Have a mainviewcontroller and on it have UIToolbar which has a UIBarButtonItem Info which shows UIViewcontroller modally.
Now when pressing Infobutton it is showing UIViewController modally which has UITextView but not showing UINavigationController with Done button.
I am not able to figure it out what i am missing in my code.
This is how i am showing UITextView and NavigationController in UIViewController modally.
#import "ModalViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation ModalViewController
#synthesize textView;
#synthesize navBar;
#synthesize navigationController;
#synthesize delegate;
-(void)dealloc
{
[textView release];
[navBar release];
[navigationController release];
[super dealloc];
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.title = #"Info";
UINavigationController *navigationController = [[UINavigationController alloc]init];
//initWithRootViewController:viewController];
self.navigationController.navigationBar.tintColor = [UIColor brownColor];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(Done:)] autorelease];
self.textView = [[[UITextView alloc] initWithFrame:CGRectMake(0, 0, 320, 416)]autorelease];
self.textView.textColor = [UIColor whiteColor];
self.textView.font = [UIFont fontWithName:#"Georgia-BoldItalic" size:14];
//self.textView.delegate = self;
self.textView.backgroundColor = [UIColor brownColor];
self.textView.layer.borderWidth = 1;
self.textView.layer.borderColor = [[UIColor whiteColor] CGColor];
self.textView.layer.cornerRadius = 1;
self.textView.textAlignment = UITextAlignmentCenter;
self.textView.text = #"This is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.\nThis is UITextView presenting modally.
self.textView.editable = NO;
//[self.view addSubview:navigationController.view];
[self.view addSubview: self.textView];
//[navigationController release];
}
And this is how UIViewController presented modally
//Create a final modal view controller
UIButton *modalViewButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[modalViewButton addTarget:self action:#selector(modalViewAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:modalViewButton];
self.navigationItem.rightBarButtonItem = modalBarButtonItem;
- (void) modalViewAction:(id)sender
{
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]autorelease];
//self.viewController = [[ModalViewController alloc] init];
[self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//ModalViewController *myModalViewController = [[ModalViewController alloc] init];
//UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myModalViewController];
//navigationController.navigationBar.tintColor = [UIColor brownColor];
_viewController = [[ModalViewController alloc] init];
//[navigationController pushViewController:_viewController animated:YES];
[self presentModalViewController:self.viewController animated:YES];
//[self.view addSubview:navigationController.view];
//[navigationController release];
[myModalViewController release];
}
I will appreciate if you can figure out what i m doing wrong or missing in my code.
Thanks a lot.
This seems like a needlessly convoluted way of displaying the new controller. In my apps, I do it like this:
//this function displays (modally) view controller nested inside a navcontroller
- (void) showModalController
{
YourViewController * ecreator = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
UINavigationController * navcontrol = [[UINavigationController alloc] initWithRootViewController: ecreator];
[self presentModalViewController: navcontrol animated:YES];
[navcontrol release];
[ecreator release];
}
Now you want to do the graphical setup (navbar color etc) in the initWithNib and/or viewDidLoad functions of the YourViewController.
#synthesize navigationController;
so navigationController is your class member variable.
in the function
- (void) viewDidLoad
you declare a local variable
UINavigationController *navigationController
Please notice that the second navigationController is different from your member variable navigationController .
So, inside viewDidLoad you need to create object of your member variable navigationController. Not the local variable navigationController.
Do not RE-declare navigationController in viewDidLoad. Instead, create the object using member variable like:
navigationController = [[UINavigationController alloc]init];
Try this, it worked great for me. I had the exact same problem
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#“segue_name"])
{
UINavigationController *nav = [segue destinationViewController];
ExampleViewController *exampleVC = (ExampleViewController *) nav.topViewController;
//Setup any properties here and segue
}
}

Memory Management with UIPopoverController

I wanted to double check that I was doing correct memory management. Is this correct? Do I have the correct amount of releases.
In my .h file:
UITableView *_sortOrderTableView;
#property (nonatomic, retain) UITableView *SortOrderTableView;
In my .m file:
In dealloc
[_sortOrderTableView release];
My code that presents the popover is this:
- (IBAction)sortButtonOrderPressed:(id)sender {
UIViewController *sortOrderController = [[UIViewController alloc] init];
self.SortOrderTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
self.SortOrderTableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"App_Background.png"]];
self.SortOrderTableView.bounces = NO;
self.SortOrderTableView.scrollEnabled = NO;
sortOrderController.view = self.SortOrderTableView;
sortOrderController.contentSizeForViewInPopover = CGSizeMake(200, 100);
self.SortOrderTableView.delegate = self;
self.SortOrderTableView.dataSource = self;
self.SortPopover = [[UIPopoverController alloc] initWithContentViewController:sortOrderController];
[self.SortPopover presentPopoverFromRect:_sortButtonOrder.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[self.SortOrderTableView release];
[sortOrderController release];
}
Remove [self.SortOrderTableView release];, it should be [_sortOrderTableView release]; or self.SortOrderTableView = nilanyway, but you're already calling that in your dealloc method, so there is no need to release it here. If you want to release it though, use self.SortOrderTableView = nil.
Apart from that you will also have to release your SortPopover's instance variable in your dealloc method.

UITabBarContrtoller achieve from a different class in iPhone

I have the following problem:
There is a class that includes five tabs in the following way:
mainMenuClient.h
#import <UIKit/UIKit.h>
#interface MainMenuClient : UIViewController {
UITabBarController *tabBarController;
}
#property (nonatomic, retain) UITabBarController *tabBarController;
#end
mainMenuClient.m
-(void)viewDidLoad {
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor blackColor];
self.view = contentView;
[contentView release];
ContactListTab *contactTab = [[ContactListTab alloc] init];
ChatTab *chat = [[ChatTab alloc]init];
DialerTab *dialer = [[DialerTab alloc]init];
MenuTab *menu = [[MenuTab alloc]init];
TesztingFile *teszting = [[TesztingFile alloc]init];
contactTab.title = #"Contact List";
chat.title = #"Chat";
dialer.title = #"Dialer";
menu.title = #"Menu";
teszting.title = #"TesztTab";
contactTab.tabBarItem.image = [UIImage imageNamed:#"Contacts_icon.png"];
chat.tabBarItem.image = [UIImage imageNamed:#"Chat_icon.png"];
dialer.tabBarItem.image = [UIImage imageNamed:#"Dialer_icon.png"];
menu.tabBarItem.image = [UIImage imageNamed:#"Menu_icon.png"];
teszting.tabBarItem.image = [UIImage imageNamed:#"Contacts_icon.png"];
chat.tabBarItem.badgeValue = #"99";
tabBarController = [[UITabBarController alloc]init];
tabBarController.view.frame = CGRectMake(0, 0, 320, 460);
[tabBarController setViewControllers:[NSArray arrayWithObjects:contactTab, chat, dialer, menu, teszting, nil]];
[contactTab release];
[chat release];
[dialer release];
[menu release];
[teszting release];
[self.view addSubview:tabBarController.view];
[super viewDidLoad];
}
In the contactTab class there are a UITableViewController.
contactTab.h
- (void)updateCellData;
- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath;
There is a third class, which I would like to achieve is a method of UITableViewController's (from ContactTab).
So far I tried this:
When I tried to achieve the UItabbarController:
MainMenuClient *menu;
UITabBarController *tabBarControllerchange = [[UITabBarController alloc] init];
tabBarControllerchange = menu.tabBarController;
[tabBarControllerchange setSelectedIndex:0];
When I tried to achieve the UITableViewController:
ContactListTab *contactListTab;
[contactListTab updateCellData];
Does anybody have an idea for this problem? Thanks. Balazs.
You need to get the instance of your MainMenuClient:
define method in your MainMenuClient.h as:
+(MainMenuClient*)getMainMenuInstance;
Implement the following method in MainMenuClient.m as :
+(MainMenuClient*)getMainMenuInstance
{
return self;
}
Now you can get same instance of UITabBarContrtoller in any class as :
MainMenuClient *menuClient = [MainMenuClient getMainMenuInstance];
UITabBarContrtoller *newTabBarController = menuClient.tabBarController;
You can do what ever you want to do with this new UITabBarController object.
Hope this helps.
Jim.