How to override "searchBar" property in subclass of UISearchController? - ios

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

Related

UISearchController - blank space hides status bar

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.

Subclass tool bar

I added a toolbar on top of the keyboard, it appears every-time the user clicks on a TextView, it also has a number of buttons that change and interact with the TextView, like for example, changing the text font.
What I'm trying to do now is to create a subclass of the Toolbar so that it can be used on other TextViews, but my problem is:
How to use the TextView delegate methods from inside the Toolbar subclass?
Here is my current code(not all code, for not making the post too big):
.h
#import <UIKit/UIKit.h>
#interface CustomUIToolbar : UIToolbar{
UIButton *btn1;
UIButton *btn2;
UIButton *btn3;
}
.m
#implementation CustomUIToolbar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIBarButtonItem *one = ...
UIBarButtonItem *two = ...
UIBarButtonItem *three = ...
self.barStyle = UIBarStyleDefault;
self.layer.borderWidth = 1;
self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.items = [NSArray arrayWithObjects:one,placeholder,two,three,four,five,nil];
[self sizeToFit];
}
return self;
}
-(void)actionBtn3:(UIButton *) barBtnItem{
...
}
-(void)actionBtn2:(UIButton *) barBtnItem{
...
}
-(void)actionBtn1:(UIButton *) barBtnItem{
...
}
// And the UITextView Delegate Methods
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
...
return YES;
}
- (void)textViewDidChangeSelection:(UITextView *)textView {
...
}
Your CustomUIToolbar class should conform to UITextViewDelegate protocol:
#interface CustomUIToolbar : UIToolbar <UITextViewDelegate> {
Then you need to assign your CustomUIToolbar subclass as a delegate to textView:
self.textView.delegate = self.customTabbar;
Update:
I think the problem because your toolbar instance is released before the delegate method is called on it. Try to make a property to make sure that variable stays in memory. So instead of:
UIToolbar *tool = [[CustomUIToolbar alloc] init];
Create a property:
#property(nonatomic, strong) CustomUIToolbar *tool;
And initialize it:
self.tool = [[CustomUIToolbar alloc] init];
You can make another class for UIextView and import toolbar class in it and call bar button click method from this class. and use textview of this class where it need.

UITextField, hided Keyboard, TopBar still there

i have a VC with a UITextField. Thats my Code:
.h
#interface GameOverViewController : UIViewController <UITextFieldDelegate> {
}
.m
#implementation UITextField (DisableCopyPaste)
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return NO;
return [super canPerformAction:action withSender:sender];
}
#end
#implementation GameOverViewController
NSString *text1;
text1 = #"";
UIView* testView = [[UIView alloc] init];
_nameField.inputView = testView;
[_nameField becomeFirstResponder];
_nameField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
This is for hiding the Keyboard:
UIView* testView = [[UIView alloc] init];
_nameField.inputView = testView;
But now there is still the TopBar of the Keyboard on my View:
If i take out this two lines of code, the whole Keyboard appears:
i can't get it hided. i don't want this bar.
if i disable the UITextField, the Bar is gone.
Found the solution:
in iOS 9 there is an UITextInoutAssistantItem, and here is my Solution for this Bar:
if ([self respondsToSelector:#selector(inputAssistantItem)]) {
UITextInputAssistantItem *item = [self inputAssistantItem];
item.leadingBarButtonGroups = #[];
item.trailingBarButtonGroups = #[];
}

Add UISearchBar to UITableView programmatically not working

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

Two UISearchBars showing up in a view controller when only one is instantiated

I have two search bars shhowing up in a view controller. It's strange because I have the same exact code in another vc and it works fine. (the search bar in the background shouldn't be there)
here's a screenshot:
I added the delegates: <UISearchBarDelegate, UISearchDisplayDelegate>
then in the .h:
#property (nonatomic,retain) IBOutlet UISearchBar *searchBar;
in the .m:
#synthesize searchBar;
in the viewDidLoad:
self.searchBar.frame = CGRectMake(204, 11, 107,44);
self.searchBar.delegate = self;
//customize the searchbar
UITextField *searchField = [self.searchBar valueForKey:#"_searchField"];
[searchField setBackground:[UIImage imageNamed:#"search_panel.png"]];
[self.searchBar setTintColor:[UIColor redColor]];
UIImage *searchimg = [UIImage imageNamed:#"searchfield_bg.png"];
for (UIView *subview in self.searchBar.subviews) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
UIView *bg = [[UIView alloc] initWithFrame:subview.frame];
bg.backgroundColor = [UIColor colorWithPatternImage:searchimg];
[self.searchBar insertSubview:bg aboveSubview:subview];
[subview removeFromSuperview];
break;
}
}
[self.view addSubview:self.searchBar];
and that's it. I have nothing to do with the searchBar in the Storyboard view controller xib it's added programmatically in the viewDidLoad method
thanks for any help
If you're using an outlet, your UISearchBar very likely also exists in the storyboard or the xib. Since you're also creating it in the viewDidLoad, you're making a second copy of it. Take another look at your storyboard.

Resources