Hi: I want to display a section index in an UITableView with a search bar in the table view header (not section header).
But the index strip is now overlapping the search bar. Is there an elegant solution to avoid this and let the index start below the table header?
I realize this answer comes very late, but I had the same problem and searched here and elsewhere. I found good answers here:
Changing the size of the UISearchBar TextField?
There are several suggestions, but the one I found most straightforward was to put a UISearchBar and UINavBar in a UIView and pass that view to setTableView. The problem is that the table controls the size of the header view, ignoring any setting you add. So adding the view makes the table happy and you can reach inside and set the search bar size without being interfered with by the table.The UINavBar has the same background styles as the UISearchBar, so fills the extra space in a visually consistent way, though you have to tweak its frame - See below:
UISearchBar searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 1, 290, 40)] autorelease];
UIView *searchView = [[[UIView alloc] initWithFrame:CGRectMake(0, 1, 320, 40)] autorelease];
UINavigationBar *navBar = [[[UINavigationBar alloc] initWithFrame:CGRectMake(1, -1, 320, 41)] autorelease]; // same gradient/style as search bar
[navBar setTintColor:[UIColor lightGrayColor]];
[searchView addSubview:navBar];
[searchView addSubview:searchBar];
I add empty strings to indexes array:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
NSMutableArray *array = [NSMutableArray arrayWithArray:_sortedKeys];
[array insertObject:#"" atIndex:0];
[array insertObject:#"" atIndex:0];
return array;
}
Related
I'm new to ios, but I couldn't find the answer anywhere.
I got a UITableView showing products. In the HeaderView I got a UISearchBar. The idea is that with the SearchBar you can filter the rows in the TableView. I don't want to / can't use the "TableView" the SearchBar lays on top, so I hid it with searchDisplayController.searchResultsTableView.hidden = YES;. This works finde, the rows get filtered and the user can click on a desired element.
The Problem is that my TableView isn't scrollable anymore! How can I avoid this? I set self.tableView.scrollEnabled = YES; in searchBarTextDidBeginEditing.
visual demonstration: http://d.pr/i/vqiK
Thanks for your help.
How I added the SearchBar to the TableView:
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, SEARCHBAR_WIDTH_EXPAND, SEARCHBAR_HEIGHT)];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.tableView.tableHeaderView = searchBar;
searchBar.delegate = self;
I have a UIViewController and I wish to place a simple UITabBar like the in the screenshot below: I don't want to use an UITabBarController. In fact, my original setup uses one, and it's easy as cake to get it to work.
However, the thing is I found out it's a bad idea to put UITabBarControllers inside Navigation Controllers, so I'm forced to refactor the hierarchy (so please don't suggest using one).
Given an UIViewController, how can I add an UITabBar on the bottom programatically? I got my UITabBarDelegate all setup to show a specific view when 1 of the tab bars is clicked, but the problem is when the view controller loads, no tab bar shows up! Here's my code to do that:
- (void) viewDidLoad {
...some initialization...
CGRect frame = CGRectMake(0, 431, 320, 49);
profileItem = [[UITabBarItem alloc] init];
profileItem.image = icon;
profileItem.title = #"Diet";
tabBar = [[UITabBar alloc] initWithFrame:frame];
NSArray* items = [[NSArray alloc] initWithObjects:profileItem, nil];
tabBar.items = items;
tabBar.delegate = self;
[tabBar setSelectedItem:[tabBar.items objectAtIndex:0]];
[self.view addSubview:tabBar];
[super viewDidLoad];
}
What am I missing here?
EDIT: Argh, I found out it has to do with the frame... Hmm.. what y-coordinate should I use if I have an existing navigation header on top?
You mention in your edit that you already determined that it has to do with the frame. Your problem may stem from the fact that your view's size in viewDidLoad isn't guaranteed to be the same is it will be when it eventually gets displayed. UIKit resizes the view to fit the context in which it's being displayed just before viewWillAppear:.
If you want to add the tab bar in viewDidLoad, then you should position it at the bottom of your view's frame by doing some math:
CGRect frame = CGRectMake(0, self.view.bounds.size.height - 49,
self.view.bounds.size.width, 49);
Then set an appropriate autoresizingMask so that it remains at the bottom even if UIKit resizes your view:
tabBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
I'm trying desperately to design my UI programmatically.
But I think I'm in trouble to understand the concept.
Basically I want a UI which contains different UIViews and a UITableView.
But now I'm stuck with the UITableView.
So my "main view" which should contain all these views is called AddListViewController(it inherence from UIViewController).
In the loadView method of this class I'm trying to add a table, but no chance. Has anyone a good example for me. I'm really dont see the point for a separate UITableView and UITableViewController.
You can create a new UITableView, very simply like this:
UITableView * tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStylePlain];
[tableView setDataSource:self];
[tableView setDelegate:self];
[self.view addSubview:tableView];
[tableView release];
EDIT: The above answer beat me to it.
Just create your UITableView and add it as subview:
UITableView *table =
[[UITableView alloc] initWithFrame:CGRectMake(x, y, width, height)
style:UITableViewStyleGrouped];
...
[self.view addSubview: table];
[table release];
In loadView, you have to make every view - including the overall view associated with the view controller.
You perhaps want to do what you are trying to do in viewDidLoad instead?
i many be late in answering but still i am answering it
use:
shareListView.delegate = self;
shareListView.dataSource = self;
I have a view that was created with all of the default UITableView stuff, but now I need to add a header area above where the UITableView is (so the UITableView will scroll normally, but the top 100px of the screen or so will have static header content). I don't see where I can resize the UITableView in IB, and am not sure how to do this.
Does anyone know?
You can use UITableViewDelegate methods to create a custom header view for a table and specify the height, namely tableView:viewForHeaderInSection: and tableView:heightForHeaderInSection:. You can add whatever you like to the view. Here's an example that adds a right aligned UILabel:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,30)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, headerView.frame.size.width-120.0, headerView.frame.size.height)];
headerLabel.textAlignment = NSTextAlignmentRight;
headerLabel.text = [titleArray objectAtIndex:section];
headerLabel.backgroundColor = [UIColor clearColor];
[headerView addSubview:headerLabel];
return headerView;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30.0;
}
Why don't you use the UITableView provided header?. As follow:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"My Title";
}
Additionally you may resize your table view in IB by dragging the borders.
When you add a UIView or one of its subclasses onto the UITableView using IB (just drag a UIView and drop it onto the UPPER part of UITableView of yours), it automatically adds that UIView component and makes it the "tableHeader" component.
Each UITableView has one tableHeader and one tableFooter component reserved...
This way the new view would be a part of the UITable, and scroll with it or appear/disappear or whatever you do to the table. You can change its hidden property if you need conditional behavior.
On the other hand, if you want the header view stay put, as the table scrolls, then it is better to make the table smaller and put the header above it as suggested in other answers...
I finally solved this problem the right way without changing the base class. The one answer to add the view to the parent nav controller is nice but the transitions look horrible.
The fix is actually easy. The trick is to create custom setter and getter for self.tableView property. Then, in loadView, you replace the view with a fresh UIView and add the tableView to it. Then you're free to add subviews around the tableView. Here's how it's done:
In header:
#interface CustomTableViewController : UITableViewController
{
UITableView *tableView;
}
In .m:
- (UITableView*)tableView
{
return tableView;
}
- (void)setTableView:(UITableView *)newTableView
{
if ( newTableView != tableView )
{
[tableView release];
tableView = [newTableView retain];
}
}
- (void)loadView {
[super loadView];
//save current tableview, then replace view with a regular uiview
self.tableView = (UITableView*)self.view;
self.view = [[UIView alloc] initWithFrame:self.tableView.frame];
[self.view addSubview:self.tableView];
//code below adds some custom stuff above the table
UIView *customHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
customHeader.backgroundColor = [UIColor redColor];
[self.view addSubview:customHeader];
[customHeader release];
self.tableView.frame = CGRectMake(0, customHeader.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - customHeader.frame.size.height);
}
- (void)viewDidUnload
{
self.tableView = nil;
[super viewDidUnload];
}
Enjoy!
You will have to embed the UITableView in a UIView alongwith another view (which you are referring to as header section).
So, the UIView will have 2 subviews. The header view followed by the table view.
UIView(parent)
UIView (header)
UITableView (table)
Hope this helps.
I like the answer from noodl_es (upvoted), because it provides the functionality and behavior you want, yet you don't have to worry about resizing the UITableView: that is handled for you automatically. However, the solution is best suitable only if the header information pertains specifically to the first section of the table (or if the table has only one section). If the table has more than one section, then the header of the second section will push away the header of the first section when scrolled up, and therefore the header view will not appear to pertain to the whole table.
Found a solution at iphonedevsdk
Instead of doing this:
[tableViewController.view addSubview:viewSubclass];
do this
[tableViewController.navigationController.view addSubview:viewSubclass];
Suppose to have your UITableViewController
#interface MXMTableViewController : UITableViewController <UITableViewDelegate,UIScrollViewDelegate> {
/// your table view interface here
}
and a xib with you simple UITableView defined yet in it, you can do as Mihir says overriding the loadView method like this:
- (void)loadView {
[super loadView];
UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view = mainView;
[mainView release];
// Add Header View
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 36)];
headerView.backgroundColor = [UIColor redColor];
[self.view addSubview:headerView];
// now, move your table view down. Check you nib to choose
// the right Y-axis offset
CGRect f = tableView.frame;
f.origin.y += headerView.frame.size.height/2;
tableView.frame = f;
// Add the table view to the container view
[self.view addSubview:self.tableView];
// Add footer
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.frame.size.height, 320, 125)];
footerView.backgroundColor = [UIColor redColor];
[self.view addSubview:footerView];
[footerView release];
[headerView release];
}
...and that's it. You have a UITableView with fixed header and footer.
PS. You may now use your xib custom views as the header and footer's views.
Expecting your well advice!
I have a TableView(Grouped Table created via I.B). I'm showing some data on the table when code executes using Navigation Controller view. I want to add a "Tab Bar" in my Table view whether through I.B (or) Programmatically. For ex: Launch built-in "Clock" app, where you can see a Tab Bar which has options of 'World Clock', 'Alarm', 'Stop Watch' and 'Timer' in single view itself.
I tried to create like same by adding a 'Tab Bar' in I.B, but drag and drop of Tab Bar doesn't sit in the Table View. I don't know why. (or) else i even tried programmatically to create it in the Table View, but not succeeded. Is it not possible?
Can anyone please help me on pointing out the code or samples?
thanks.
Calve/
I think you are taking the wrong approach. Adding a tab bar to your table view is wrong. You are supposed to start with the tab bar app and add a navigation controller to that tab bar app. Inside the navigation controller you can add a view with a table on it.
You need to add it to your parent controller's view. Also the tempView element is not necessary.
E.g. if the app uses a navigation controller as the main view controller you would add this to your custom UITableViewController class:
- (void)viewDidLoad
{
[super viewDidLoad]; UITabBar* tabBarView = [[UITabBar alloc] initWithFrame:CGRectMake(0, 430, 320, 50)];
NSArray* tabbarItems = [[NSArray alloc] initWithObjects:[[UITabBarItem alloc] initWithTitle:#"Item1" image:nil tag:1],[[UITabBarItem alloc] initWithTitle:#"Item2" image:nil tag:2],[[UITabBarItem alloc] initWithTitle:#"Item3" image:nil tag:3], nil];
tabBarView.items = tabbarItems;
[self.navigationController.view addSubview:tabBarView];
}
Try creating a UIView and adding a tabBar to that view, and now place this view inside your table. I tried this and its working,
So your function cellForRowAtIndexPath will look like this
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
UITabBar* tabBarView = [[UITabBar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
NSArray* tabbarItems = [[NSArray alloc] initWithObjects:[[UITabBarItem alloc] initWithTitle:#"Item1" image:nil tag:1],[[UITabBarItem alloc] initWithTitle:#"Item2" image:nil tag:2],[[UITabBarItem alloc] initWithTitle:#"Item3" image:nil tag:3], nil];
tabBarView.items = tabbarItems;
[tempView addSubview:tabBarView];
[cell addSubview:tempView];
return cell;
}
So now instead of using default cell you can customize it to the way you want.Also I havent considered memory release issue so u might need to update the code to release the allocated memory.