Why is UISearchBar not shown correctly? - iphone

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];

Related

When does searchDisplayController delegate methods get called?

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.

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
}
}

White line above UISearchDisplayController

I got a problem with the uisearchdisplaycontroller.
If I add the controller's searchbar to a tableviews headerview it shows a thin white line above the searchbar! If I add the searchbar without the searchcontroller it shows it correctly. Important is that u take a really close look to the standard searchdisplaycontroller or customize it a bit, otherwise you will not be able to see the line.
Does anyone knows a way to avoid the white line?
Code in init methode of BaseViewController : UIViewController
searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[searchBar sizeToFit];
searchBar.showsCancelButton = NO;
searchBar.barStyle = UIBarStyleDefault;
searchBar.hidden = NO;
searchBar.delegate = self;
searchBar.placeholder = #"Suche";
searchCtrl = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar contentsController:self];
searchCtrl.delegate = self;
searchCtrl.searchResultsDataSource = self;
searchCtrl.searchResultsDelegate = self;
[searchCtrl searchResultsTableView].scrollsToTop = NO;
Code in StartViewController : BaseViewController in viewWillAppear
tableController.tableView.tableHeaderView = searchCtrl.searchBar;
searchBar.hidden = NO;
if ( [tableController.tableView contentOffset].y == 0.0 )
{
[tableController.tableView setContentOffset:CGPointMake(0.0, 44.0) animated:NO];
}
Nothing special, for me it has to do with the UISearchDisplayController not with the implementation, cause if u only use the searchbar everything is fine
set searchBar.clipsToBounds = YES;

Problem: Can´t pass a NSUInteger from one ViewController to the other anymore

I want pass a number from my ViewController to the the TweetViewController. Everything worked okay, I did it with NSUInteger as property (randomNumber and tweetNumber):
TweetViewController *Second = [[TweetViewController alloc] initWithNibName:nil bundle:nil];
Second.tweetNumber = randomNumber;
Second.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:Second animated:YES];
[Second release];
I have now changed my code because I did not want that only my TweetViewVontroller is loaded. I wanted a homescreenlike swipe between the Tweet- and InfoViewController. I use a SwitchViewController, which will be load instead of the TweetViewController. The SwitchViewController looks like this (window1/2 are UIViewController):
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320,460)];
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0,0,640,460)];
self.window1 = [TweetViewController alloc];
self.window2 = [InfoViewController alloc];
[contentView addSubview:self.window1.view];
CGRect f = self.window2.view.frame;
f.origin.x = 320;
self.window2.view.frame = f;
[contentView addSubview:self.window2.view];
[scrollView addSubview:contentView];
scrollView.contentSize = contentView.frame.size;
scrollView.pagingEnabled = YES;
self.view = scrollView;
[contentView release];
[scrollView release];
Now I can´t pass the number from the FirstViewController to the TweetViewController. Any Idea, how to solve the problem?
window1.tweetNumber = randomNumber;
If you want to update this every time the scrollview is scrolled, you might want to look into the UIScrollViewDelegate protocol. Specifically scrollViewWillBeginDragging: