I'm using a UISearchController and it is working fine. However it is leaving a blank space over the search bar (when it is focused) which partially hides the status bar. This espace
I already tried setting the self.edgesForExtendedLayout = UIRectEdgeNone also self.navigationController.extendedLayoutIncludesOpaqueBars = YES but the space is still there. I tried setting the self.definesPresentationContext = YES;but it generated that the searchBar take the status bar position like this.
I'm using a UIViewController embedded in a UINavigationController. This is the setUp that im implementing now:
#interface DirectoryViewController : UIViewController <UITableViewDataSource , UITableViewDelegate ,UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>
#property (strong, nonatomic) NSMutableArray *personsArray;
#property (nonatomic, strong) UISearchController *searchController;
#property (nonatomic, strong) NSMutableArray *searchResults;
#implementation DirectoryViewController
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:#"TableSearchResultsNavController"];
// Our instance of UISearchController will use searchResults
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
// The searchcontroller's searchResultsUpdater property will contain our tableView.
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self;
//Cancel button tint
_searchController.searchBar.tintColor = [UIColor whiteColor];
[self.searchController.searchBar setBackgroundImage:[UIImage imageNamed:#"navBar"]
forBarPosition:0
barMetrics:UIBarMetricsDefault];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) { /// iOS 7 or above
self.edgesForExtendedLayout = UIRectEdgeNone;
}
self.navigationController.extendedLayoutIncludesOpaqueBars = YES;
}
I appreciate any help. Thanks
I found the solution in This answer.
Changing the tableInsets:
self.directoryTable.contentInset = UIEdgeInsetsMake(-10, 0, 0, 0);
when the searchController is becameFirstResponder
and
self.directoryTable.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
when the search bar action is finished.
Related
I created a NavigationBar and added it to the UIViewController. But after init, the reference turns to nil. I'm new to iOS and OC, I don't know why. Anyone can help? Thank you.
code summary:
#interface ContainerViewController()
#property (nonatomic, retain) UINavigationBar *nav;
#property (nonatomic, retain) UINavigationItem *navItem;
#end
#implementation ContainerViewController
- (instancetype) initWithParams:(NSDictionary *)params {
self = [super init];
if (self) {//...}
return self;
}
- setNavTitle:(NSDictionary *) params {
NSString *title = params[#"title"];
/////////////////////////////////
// here goes wrong
// self.navItem == nil here, why?
/////////////////////////////////
self.navItem.title = title;
}
- (void) viewWillAppear:(Bool)animated {
[super viewWillAppear:NO];
static float navHeight = 64.0;
UIViewController *wvController = [WebView init here];
UINavigationBar *nav = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), navHeight)];
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:title];
nav.items = [NSArray arrayWithObjects: navItem, nil];
///////////////////////////////
// I saved the reference here
//////////////////////////////
[self setNav:nav];
[self setNavItem:navItem];
[self.view addSubview:nav];
[self addChildViewController:wvController];
wvController.view.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - navHeight);
[self.view addSubview:wvController.view];
[wvController didMoveToParentViewController:self];
}
#end
This will be useful for you, kindly check and do
Tutorial point site is very easy to learn some important UI basics if you are working in Objective C
I have the problem like this: Hide UISearchBar Cancel Button
I have subclassed UISearchController and UISearchBar, and override methods layoutSubviews in UISearchBar.
How to override searchBar property with custom UISearchBar in my custom UISearchController?
Update 1
To implement property with custom UISearchBar i do in MyUISearchController:
#property(nonatomic, strong, readonly) UISearchBar *searchBar;
And
#synthesize searchBar=_searchBar;
- (UISearchBar *)searchBar {
return [MySearchBar new];
}
But UISearchController uses default searchBar anyway..
Update
In h file:
#interface MySearchController : UISearchController <UITableViewDelegate, UITableViewDataSource>
In m file:
#interface MySearchController () <UISearchDisplayDelegate, UISearchControllerDelegate,
UISearchBarDelegate, UISearchResultsUpdating, SearchAutocompleteLoader>
#property UISearchController *searchController;
#property (strong, nonatomic) UITableView *searchResultTable;
#property UIView *viewForSearchBar;
#property (nonatomic) NSInteger filterSettings;
#property (strong, nonatomic) UILabel *matchesLabel;
#property (strong, nonatomic) UIView *loading;
#property (strong, nonatomic) UIView *foggView;
#end
- (instancetype)initWith:(UIView *)viewForSearch foggView:(UIView *)view delegate:(id)delegate andResultTableView:(UITableView *)tableView
{
self.viewForSearchBar = viewForSearch;
self.searchResultTable = tableView;
self.foggView = view;
self.searchDelegate = delegate;
[self configureSearchController];
return self;
}
- (void)configureSearchController {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
[self loadFilterSettings];
self.searchController.searchBar.delegate = self;
[self.searchController.searchBar setShowsCancelButton:NO];
//self.searchController.searchBar.searchBarStyle = UISearchBarStyleDefault;
[self.searchController.searchBar setBackgroundImage:[UIImage imageWithCGImage:(__bridge CGImageRef)([UIColor clearColor])]];
[self.searchController.searchBar setImage:[UIImage imageNamed:#"iconSearchSettings"] forSearchBarIcon:UISearchBarIconBookmark state:UIControlStateNormal];
self.searchController.searchBar.frame = CGRectMake(0, 0, self.view.frame.size.width, self.viewForSearchBar.frame.size.height);
self.viewForSearchBar.tintColor = [UIColor yellowColor];
// [self.viewForSearchBar addSubview:self.searchController.searchBar];
self.searchController.searchBar.barTintColor = [UIColor whiteColor];
self.searchController.searchBar.tintColor = [UIColor blackColor];
//self.searchController.searchBar.backgroundColor = [UIColor whiteColor];
[self.viewForSearchBar addSubview:self.searchController.searchBar];
for (UIView *subView in self.searchController.searchBar.subviews) {
if ([subView isKindOfClass:[UITextField class]]) {
[subView setTintColor:[UIColor blueColor]];
[[(UITextField *) subView valueForKey:#"textInputTraits"] setValue:[UIColor blueColor] forKey:#"insertionPointColor"];
}
}
[self.searchController setActive:YES];
[self.searchController setActive:NO];
}
UISearchController's searchBar is a computed property, you have to store your custom searchBar and return it when call searchBar.
Here is some code in Swift:
var mySearchBar = MySearchBar()
override var searchBar: UISearchBar {
get{
return mySearchBar;
}
}
In order to customize the searchBar property begin the customization process by subclassing first the search bar (UISearchBar). Then, use this custom search bar in the subclass of the search controller, and at the end use both of them in the your ViewController class.
Refer this tutorial:
UISearchController Customization
import UIKit
class MySearchController: UISearchController {
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
searchBar.showsCancelButton = false
}
}
See this one tutorial for customise the UISearchBar in Swift:
Customise UISearchBar
Objective - C : Add the code in ViewDidLoad. You have already declare object of UISearchBar
[searchBar setShowsCancelButton:NO];
Swift : in ViewDidLoad
searchBar.showsCancelButton = false
In my app I have a UIViewController that lets users search in a server database. (It's not filtering an existing list.) Results are displayed in a UITableView, which is the searchResultsController of the custom UISearchController.
We need a different behaviour of the 'Cancel' button so we created subclasses of UISearchController and UISearchBar.
My issue is: VoiceOver doesn't see the UITableView that display results. Instead of selecting the header, then the first row and so on, it selects the whole area and reads something about closing the view. (There's no 'Close' button). It seems like the UITableView showing the results is hidden. Here's the view hierarchy when the searchResultsController is presented.
If I initiate the searchController with the default class, I get the correct behaviour (for VoiceOver, not for the 'Cancel' button).
The documentation doesn't say anything specific about subclassing.
Any hint?
Here's the code when we initialize them:
//Showing results
self.resultsTableController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
self.resultsTableController.tableView.delegate = self;
self.resultsTableController.tableView.dataSource = self;
self.resultsTableController.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// Configuring searchController
self.searchController = [[RedactedNameSearchController alloc] initWithSearchResultsController:self.resultsTableController];
// When initialized with UISearchController, it works:
// self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsTableController];
[self.searchController.searchBar sizeToFit];
self.searchController.searchBar.delegate = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self ;
UISearchController subclass code:
#interface MySearchController () {
UISearchBar *searchBar;
}
#end
#implementation MySearchController
- (UISearchBar *)searchBar
{
if (searchBar == nil) {
searchBar = [[MySearchBar alloc] initWithFrame:CGRectZero];
searchBar.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
}
return searchBar;
}
#end
`UISearchBar is implemented like so:
#implementation MySearchBar
-(void)setShowsCancelButton:(BOOL)showsCancelButton {
}
-(void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
}
#end
Background: I have a UIViewController that, when loads, has a UITableView generated programmatically that gets its data from an SQLite3 database. This works fine.
Problem: I need to add a UISearchBar (and associated logic) but when I try, the UISearcBar is not rendered.
Code so far:
.h file:
#import <UIKit/UIKit.h>
#import "sqlite3.h"
#import "Exhibitor.h"
#interface ExhibitorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate>
{
sqlite3 *congressDB;
NSMutableArray *searchData;
UISearchBar *searchBar;
UISearchDisplayController *searchDisplayController;
}
#property (strong, nonatomic) IBOutlet UITableView *tableView;
-(NSString *) filePath;
-(void)openDB;
#end
.m file where the UISearchBar is added:
-(void)loadTableView
{
CGRect usableSpace = [[UIScreen mainScreen] applicationFrame];
CGFloat usableWidth = usableSpace.size.width;
CGFloat usableHeight = usableSpace.size.height;
UITableView *tableView = [[UITableView alloc] init];
[tableView setFrame:CGRectMake(0,0,usableWidth, usableHeight)];
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 64)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableView.tableHeaderView = searchBar; // I think this should have loaded the searchBar but doesn't
// [self.tableView setTableHeaderView:searchBar]; // Have also tried this
// [self.tableView.tableHeaderView addSubview:searchBar]; // And this
NSLog(#"searchBar = %#", searchBar); // This shows the searchBar is an object with values
NSLog(#"HeaderView = %#", self.tableView.tableHeaderView); // This shows the tableHeaderView as null ??
}
What am I doing wrong? What do I need to do to add a UISearchBar programmatically to a UITableView within a UIVewController?
You should use a UITableViewController instead...
.h
#interface ExhibitorViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate> {
sqlite3 *congressDB;
NSMutableArray *searchData;
UISearchBar *searchBar;
UISearchDisplayController *searchDisplayController;
}
-(NSString *) filePath;
-(void)openDB;
#end
.m
-(void)loadTableView {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 64)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
self.tableView.tableHeaderView = searchBar;
}
The problem is you were creating a table view but not assigning it to the property, and using UITableViewController makes things much simpler anyway...
If you want to keep it the way it is now, then you could just put self.tableView = tableVew; after [self.view addSubview:tableView];...
The problem is that
self.tableView
in loadTableView is nil or it is not that table that you have created programmatically.
Add
self.tableView = tableView;
after
[self.view addSubview:tableView];
Without this your searchBar is added to invalid tableView.
should
I currently have a table view controller and have placed a UISearchDisplayController on top or above the my table view controller inside the interface builder. Inside the viewDidLoad of my implementation file I go ahead and assign the searchbar to the navigationItem.titleView. The problem that I now have is that there is a bit more space in the first table view cell because it still thinks that the searchdisplaycontroller is there. You can see it here: http://imgur.com/u6cQew2
Here is code:
.h file
#interface searchTableViewController : UITableViewController <UISearchBarDelegate>
{
UISearchBar *searchDrugBar;
}
#property (nonatomic, strong) IBOutlet UISearchBar *searchDrugBar;
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
searchDrugBar.placeholder = #"Search for info";
self.navigationItem.titleView = self.searchDisplayController.searchBar;
[self.searchDisplayController setActive: YES animated: YES];
[self.searchDisplayController.searchBar becomeFirstResponder];
}
Any suggestions or ideas? Thanks in advance!
Try to create the searchBar programatically, I don't see any added value from creating it in the storyboard unless you have your own reason.
First remove it from the storyboard then:
- (void)viewDidLoad
{
[super viewDidLoad];
searchDrugBar = [[UISearchBar alloc] init];
searchDrugBar.frame = CGRectMake(0, 0, 200,44); // it could be unnecessary
searchDrugBar.delegate = self;
searchDrugBar.placeholder = #"Search for info";
self.navigationItem.titleView = self.searchDisplayController.searchBar;
[self.searchDisplayController setActive: YES animated: YES];
[self.searchDisplayController.searchBar becomeFirstResponder];
}
self.navigationItem.titleView = self.searchBarTop;
=> to pur searchbar left/right :-
UIBarButtonItem *searchBarItem = [[UIBarButtonItem alloc] initWithCustomView:searchBar];
self.navigationItem.rightBarButtonItem = searchBarItem;
- (void)viewDidLoad
{
...
self.searchDisplayController.displaysSearchBarInNavigationBar = true;
self.navigationItem.leftBarButtonItem = [UIBarButtonItem new];
...
}
==> Here Given more Reference It might be Useful I hope it work for You..
How to animate add UISearchBar on top of UINavigationBar