I have added a UISearchBar programatically to my UITableView, it was showing perfectly fine untill I decided to add an offset to my UITableView to hide the UISearchBar when the view is loaded. I would like help displaying it again.
This is what my code looks like.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.contentOffset = CGPointMake(0.0f, 44.0f);
mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)];
mySearchBar.autocorrectionType = UITextAutocorrectionTypeNo;
mySearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
mySearchBar.keyboardType = UIKeyboardTypeAlphabet;
mySearchBar.delegate = self;
self.tableView.tableHeaderView = mySearchBar;
// Create the search display controller
UISearchDisplayController *searchController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
I am not really sure where to go to from here.
This code will work in both iOS6 and iOS7.
Note that in iOS7 you will loose transparency of NavigationBar
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
[self.tableView setContentOffset:CGPointMake(0, mySearchBar.frame.size.height)];
If you want to save default transparency in iOS7 use this code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
[self.tableView setContentOffset:CGPointMake(0, -20)];
}
else {
[self.tableView setContentOffset:CGPointMake(0, mySearchBar.frame.size.height)];
}
}
Related
I would like to add a progress bar between navigation bar and UISearchBar. May I know how can I implement this? Please help. Thank you.
Here is my current code in Cell.m
- (void)layoutSubviews
{
[super layoutSubviews];
CGRect barFrame = CGRectInset(self.searchBar.frame, 10.0f, 10.0f);
self.searchBar.frame = barFrame;
}
Here is my current code in ViewController.m
Did not reflect in this code after edited. _searchBar=[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, 24)];
- (void)viewDidLoad {
[super viewDidLoad];
_valueProgress = [[LDProgressView alloc] initWithFrame:CGRectMake(0,DCNaviH, ScreenW, 10.0f)];
_valueProgress.type = LDProgressSolid;
_valueProgress.color = ThemeRedColor;
_valueProgress.progress = 0.40;
_valueProgress.flat = #YES;
_valueProgress.showText = #NO;
[self.view addSubview:_valueProgress];
}
- (UISearchBar *)searchBar{
if (!_searchBar) {
_searchBar=[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, kScreenWidth, 24)];
[_searchBar setBackgroundImage:[UIImage imageNamed:#"ic_searchBar_bgImage"]];
}];
}
return _searchBar;
}
There are a few simple options for you depending on your apps UX. I think the best solution for you based on how you explained your issue would be to include the progress bar to your view and make sure it's above the other views while positioning it below the navigation bar.
_valueProgress = [[LDProgressView alloc] init];
_valueProgress.translatesAutoresizingMaskIntoConstraints = NO;
_valueProgress.type = LDProgressSolid;
_valueProgress.color = ThemeRedColor;
_valueProgress.progress = 0.40;
_valueProgress.flat = #YES;
_valueProgress.showText = #NO;
[self.view addSubview:_valueProgress];
[_valueProgress.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].isActive = YES;
[_valueProgress.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].isActive = YES;
[_valueProgress.heightAnchor constraintEqualToConstant:10.0f].isActive = YES;
if (#available(iOS 11.0, *)) {
[_valueProgress.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].isActive = YES;
} else {
[_valueProgress.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].isActive = YES;
}
And if the search bar has been added above the progress bar, you can always call [self.view bringSubviewToFront:_valueProgress] afterwards.
I need to use a searchbar but I use this code :
self.searchBar = [UISearchBar new];
_searchBar.frame = CGRectMake(0, 0, 200, 44);
_searchBar.searchBarStyle = UISearchBarStyleMinimal;
_searchBar.placeholder = #"Search stores";
_searchBar.delegate = self;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_searchController.searchResultsDataSource = self;
_searchController.searchResultsDelegate = self;
_searchController.delegate = self;
self.definesPresentationContext = YES;
self.edgesForExtendedLayout = UIRectEdgeNone;
and the result is this... I lost my hamburgare menu button and I cant change the width of the searchbar. I also have a strange gap and it seeems to be as big as my navbar. How can I get back the hamburger menu button and fix the strange gap?
Put following code into ViewDidLoad. It will work for iOS 7+
if(SYSTEM_VERSION_GREATER_THAN(#"6.1")) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
Edited
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
CGRect frame = self.searchResultsTableView.frame;
frame.origin.y = CGRectGetHeight(self.searchContentsController.navigationController.navigationBar.frame);
frame.size.height = CGRectGetHeight(frame) - CGRectGetMinY(frame);
self.searchResultsTableView.frame = frame;
frame = self.searchBar.frame;
self.searchBar.frame = frame;
[self.searchContentsController.view insertSubview:self.searchBar aboveSubview:self.searchResultsTableView];
}
One More Try to Implement this solution.
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
self.navigationController.navigationBar.translucent = YES;
}
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
self.navigationController.navigationBar.translucent = NO;
}
Note : UISearchDisplayController is deprecated in iOS 8. Apple Document
Use following code support in iOS8
searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
searchController.searchResultsUpdater = self;
searchController.dimsBackgroundDuringPresentation = NO;
searchController.hidesNavigationBarDuringPresentation = NO;
searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
Also you can download the sample code from here.
I have a UITableView which has some custom styling. This table view appears in two places in the app, one of which is inside a UIPopoverController. However when the tableview is inside the popover it takes on the default tableview styling as stated in the UI Transition Guide under "Popover".
The problem I have is that there appears to be nowhere to change this behaviour. Regardless of where I try and modify properties of the tableview the view inside the popover doesn't change.
Anyone dealt with this issue before or have any ideas?
Here is the init method of LibraryProductView where I create the table view:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.sectionOrdering = [NSArray arrayWithObjects:
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DESCRIPTION],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DOCUMENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_ACTIVE_INGREDIENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_PRODUCTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_DOCUMENTS], nil];
self.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:CGRectInset(self.bounds, 10, 0) style:UITableViewStyleGrouped];
self.tableView.backgroundColor = [UIColor whiteColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.showsVerticalScrollIndicator = NO;
[self addSubview:self.tableView];
}
return self;
}
Here is where the containing view (LibraryProductView) is added to the popover:
- (IBAction)didTouchInformationButton:(id)sender
{
if (_infoPopover != nil && _infoPopover.isPopoverVisible)
{
[_infoPopover dismissPopoverAnimated:YES];
return;
}
CGSize preferredSize = CGSizeMake(600.0f, 500.0f);
LibraryProductViewController* productController = [[[LibraryProductViewController alloc] initWithPreferredSize:preferredSize] autorelease];
productController.filterByMyCompany = NO;
productController.product = _activityInput.product;
UINavigationController* nav = [[[UINavigationController alloc] initWithRootViewController:productController] autorelease];
nav.title = _activityInput.product.name;
RELEASE(_infoPopover);
_infoPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
_infoPopover.popoverContentSize = CGSizeMake(preferredSize.width, preferredSize.height + 46);
[_infoPopover presentPopoverFromRect:_infoButton.frame inView:_infoButton permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
The LibraryProductView is created within viewDidLoad method of LibraryProductViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.libraryProductView = [[LibraryProductView alloc] initWithFrame:(usingPreferredSize ? CGRectMake(0.0, 0.0, preferredSize.width, preferredSize.height) : self.view.bounds)];
self.libraryProductView.dataSource = self;
self.libraryProductView.delegate = self;
[self.view addSubview:self.libraryProductView];
}
To set properties for the TableView you might do so in
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
[tableView setBackgroundColor:[UIColor redcolor]];
[tableView setSeparatorColor: [UIColor blueColor]];
return 1;
}
This, of course, assumes you have set UITableViewDataSource in your .h file
I'm currently trying to place a table view and search bar inside a popover but I'm getting a really weird bug. Whenever I click on the search bar, the cancel button animates in and the bar promptly lowers about the size of a status bar.
I've tried playing around with the UIBarPosition delegate, but that doesn't do anything either. I've tried just about everything I can think of so I thought I'd ask your help. Here's the code I use in the UITableViewController to add the search bar to the table header:
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, popoverWidth, singleRowHeight)];
searchBar.delegate = self;
searchBar.showsScopeBar= YES;
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;
searchDisplayController.searchResultsTableView.rowHeight = singleRowHeight;
self.automaticallyAdjustsScrollViewInsets = NO;
self.tableView.tableHeaderView = searchBar;
return self;
}
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTop;
}
Thanks!
according to Extra space above search bar when UISearchDisplayController is active
- (void)viewDidLoad {
[super viewDidLoad];
if ([self respondsToSelector:#selector(edgesForExtendedLayout:)]) { /// iOS 7 or above
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}
In iOS 5, is there a way to never hide the search bar in a UITableViewController?
I wouldn't recommend a UITableViewController for that then, a UIViewController with a UITableVIew and UISearchBar on top of it and not on the header would do the job. In a more personal opinion, I wouldn't recommend UITableViewController for anything, I find it too much strict for what it really offers. If for some reason I am using a UITableViewControllerand the customer asks me to add a new element to the screen, I am basically screwed.
I know it's an old question, but I found out a solution for this, which works with the classic UITableViewController and UTSearchDisplayController.
I created a container view for the searchBar 1st then put the searchbar inside it. The container must not clip to bounds. After this you can change the position of the searchbar relative to the container. One problem with this that this way the searchbar not handle user interactions. So we need to use our own container which get the events below its real frame.
Our container class:
#interface _SearchContainerView : UIView
#end
#implementation _SearchContainerView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if (self.subviews.count > 0) {
UISearchBar *searchBar = (UISearchBar *) self.subviews[0];
CGRect f = searchBar.frame;
f = CGRectMake(0, 0, f.size.width, f.origin.y + f.size.height);
if (CGRectContainsPoint(f, point)) return YES;
}
return [super pointInside:point withEvent:event];
}
#end
If you create the searchBar programmatically you can set the this up with a following like code:
- (void)setSearchEnabled:(BOOL)searchEnabled {
if (searchBar == nil && searchEnabled) {
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar
contentsController:self];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin
| UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchContainer = [[_SearchContainerView alloc] initWithFrame:searchBar.frame];
[container addSubview:searchBar];
container.clipsToBounds = NO;
self.tableView.tableHeaderView = container;
} else {
[searchBar removeFromSuperview];
self.tableView.tableHeaderView = nil;
searchBar = nil;
searchDisplayController = nil;
searchContainer = nil;
}
}
Then you can change the position based on the tableView's scroll position:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (searchBar == nil || searchDisplayController.isActive) return;
CGRect b = self.tableView.bounds;
// Position the searchbar to the top of the tableview
searchBar.frame = CGRectMake(0, b.origin.y, b.size.width, 44);
}
And the last part is to restore everything after searching:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
// Restore header alpha
searchContainer.alpha = 1.0;
// Place the searchbar back to the tableview
[searchBar removeFromSuperview];
[searchContainer addSubview:searchBar];
// Refresh position and redraw
CGPoint co = self.tableView.contentOffset;
[self.tableView setContentOffset:CGPointZero animated:NO];
[self.tableView setContentOffset:co animated:NO];
}