I am inheriting my view controller from UITableViewController. I have a header (logo), content (uitableview) and now I want to display the footer (uitabbar). But for some reason UITabBar is not visible. The space is being occupied by the UITableView. How can I fix this?
UPDATE 1:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.tableView.tableFooterView = self.tabBar;
}
I'm not sure you can put a UITabBar as a footer of a UITableView.
"footer of the tableView" meaning it won't be visible until you scroll your UITableView all way down past the last cell to then see the footer -- the header and footer of a tableView scrolls with the tableView content itself). Anyway in term of UX this seems very strange.
You probably want instead your UITabBar to always be visible at the bottom of your screen (and not being dependant of the scrolling of your UITableView). To do this, simply use a UITabBarController... that will then contain your UITableViewController (as the viewcontroller associated with one of its UITabBarItem)
[EDIT] See also Apple's View Controller Programming Guide and its paragraph about TabBarControllers.
Related
I have a UITableView of type plain table view with two sections and a dynamic number of rows.
Also I am returning a UIView for the section header.
Everything works perfect except when the table reloads. The section header position moves to a random position until the view begins to scroll.
Autolayout within the header view and super view seem not violating.
I have set the table footer view either nil or show paginating animation.
And the table view is within a scroll view.
Any suggestion or solution why this glitch occurs for section header.
And this glitch only occurs in iOS 9
Problem for me was independently from refresh control, although it is part of my view controller.
It was related to estimatedRowHeight and rowHeight.
I found an empirical solution. My issue happened when going back and forth between view controller and the tableview reloaded.
Because my cells have variable height, I had:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0f;
so I can deal with cell autoresize.
Apparently the problem was with the estimatedRowHeight. When I changed the value with the maximum cell row height the glitch disappeared. The table section wasn't jumping anymore. I used the view inspector to calculate the row height based on my worst use case.
Note #1
I don't know how it performs with a thousand cells. estimatedRowHeight should be used to calculate the entire content offset so considering the worst case might be
inefficient.
Note #2
When calculate the maximum cell height keep in mind to consider the case when the font size can be increased by the system preference, if the cell is registered to these changes.
My issues get resolved as follows.
Initially I have added refresh controller as a subview of table view.
_chatListRefreshControl = [[UIRefreshControl alloc] init];
_chatListRefreshControl.transform = CGAffineTransformMakeScale(0.7, 0.7);
[_chatListRefreshControl addTarget:self
action:#selector(refreshChatListView:)
forControlEvents:UIControlEventValueChanged];
[self.myChatsTableView addSubview:_chatListRefreshControl];
I have modified that to as follows: Changed the refresh indicator from table view to table view controller's property.
UITableViewController *chatTableViewcontroller = [[UITableViewController alloc] init];
chatTableViewcontroller.tableView = self.myChatsTableView;
_chatListRefreshControl = [[UIRefreshControl alloc] init];
_chatListRefreshControl.transform = CGAffineTransformMakeScale(REFRESH_INDICATOR_SCALE_FACTOR, REFRESH_INDICATOR_SCALE_FACTOR);
[_chatListRefreshControl addTarget:self action:#selector(refreshChatListView:) forControlEvents:UIControlEventValueChanged];
chatTableViewcontroller.refreshControl = _chatListRefreshControl;
[self addChildViewController:chatTableViewcontroller];
I'm trying to figure out what my options are for having the top of a UITableView be able to stay at rest about 1/3 down the screen but still be able to scroll over the top of an image above it.
I was thinking UITableView on a UIScrollView but I haven't seen this exact thing while googling around for it.
Basically I'm looking to have a header and then the table view will scroll over the top of the header without the header moving. If I set the table view below a simple uiview or imageview, it will always be below it.
Any suggestions?
Add your header as a separate view below your table view. Your table view should completely overlap the underlying view, as if it would obscure it. Then set the table view's tableHeaderView to a transparent UIView, through which you will be able to see your underlying header view. Your table view's background colour should also be clear.
CGRect headerFrame = self.underlyingHeaderView.bounds;
UIView *transparentView = [UIView alloc] initWithFrame:headerFrame];
transparentView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = transparentView;
This question should not be mixed up with this here.. These are two different things.
There is a good example how to use a UITableView Header on SO.
This all works fine and the main header is fixed on top as long as the style is set to plain.
But if I use sections, the main header no longer sticks to top and moves away while scrolling to the bottom.
In this method, I am returning the header for each section.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
In this method I am setting the height for the header section above:
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
In this method, I am setting the real table header.
- (void)viewWillAppear:(BOOL)animated {
...
self.recordTableView.tableHeaderView = headerView;
}
Is it even possible having a fixed table header, while using sections?
What is an alternative solution to this please?
If you want a UITableViewController (static cells/keyboard handling) and have a fixed header then you should use Containment. You can do this from a Storyboard by setting up a UIViewController with your fixed header and then using a Container View to embed the UITableViewController.
Once you have your containing view setup, you right-click drag from the Container View to the View Controller you want to embed - the UITableViewController in this case.
You can access and get a reference to the contained View Controller (the UITableViewController) from the Container View Controller by implementing the prepareForSegue:sender: method.
There’s no way to maintain the header of a tableView fixed, but
an useful approach when you need a unique header, is to use a UIViewController rather than a UITableViewController, and set the header (UIView) out from the tableView.
Something like this:
If you want to keep the class as a UITableViewController you can add your header as a subview to the tableview's superview. You will have to also push the tableview top inset down so your headerview doesnt hide the table.
Here is a sample code to put inside your tableViewController subclass (This example assumes your tableview controller is inside a navigation controller, so it pushes the view to below the navigation bar):
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.automaticallyAdjustsScrollViewInsets = NO;
}
-(void)addHeaderView{
CGFloat yPosition = self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height;
mainHeaderView = [[UIView alloc] init];
const CGFloat mainHeaderHeight = 44;
[mainHeaderView setFrame:CGRectMake(0, yPosition, self.view.frame.size.width, mainHeaderHeight)];
mainHeaderView.backgroundColor = [UIColor redColor];
[self.tableView.superview addSubview:mainHeaderView];
[self.tableView setContentInset:UIEdgeInsetsMake(yPosition + mainHeaderHeight, self.tableView.contentInset.left, self.tableView.contentInset.bottom, self.tableView.contentInset.right)];
}
I haven't done this, but the first thing I would think to try is to place my tableview in a UIView and make my own header there in that UIView. Seems a trivial matter to make that view appear to be the header of the table and it would certainly stay put.
I have checked all these
UITableView, make footer stay at bottom of screen?
tableFooterView property doesn't fix the footer at the bottom of the table view
iOS - viewForFooterInSection sticking to bottom of UITableView
Proper way to implement a footer in UITableView
similar questions but unfortunately my problem hasn't resolved.
I have to implement a custom header and footer views with buttons inside. I have created separate UIView's subclasses with .nib files. In my view controller, I'm calling these methods to register nibs for header and footer view.
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
CustomTableHeaderView *view = [CustomTableHeaderView header];
view.delegate = self; //setting delegate to receive callbacks as the buttons inside the view are pressed
return view;
}
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
CustomTableFooterView *view = [CustomTableFooterView footer];
view.delegate = self;
return view;
}
Where as the class method in the custom views registers a .nib file and returns the view. However the implementation is;
+ (CustomTableHeaderView*)header
{
return [[[NSBundle mainBundle]loadNibNamed:#"CustomTableHeaderView" owner:nil options:nil]objectAtIndex:0];
}
Similar implementation for footer.
The problem is that the footer view doesn't lock at the bottom when the table view scrolls. i-e, when there are more rows to fit inside the view, the footer view hides and is revealed when all the rows are scrolled down till the end. I want to lock the footer view at the bottom of the view no matter how much rows are there to scroll.
The header view has been implemented perfectly by this implementation as it is locked at the top while the rows are being scrolled, however the footer view is scrolled with the rows.
I have also tried self.tableview.tablefooterview property but it didn't help either.
Unfortunately thats not how table section footers work. In order to accomplish an anchored view at the bottom you will need to add it as a subview to your UIView manually.
If you add it as a subview to your UITableView you will need to keep it anchored by changing its frame in scrollViewDidSroll:. If you add it as a subview to the UIView containing your UITableView you can just place it statically at the bottom. In either case you probably want to adjust the contentInset of the table view with an inset at the bottom so that you can scroll your content up above the anchored footer.
I have put an UITableView inside a UIViewController and have copied code from UITableViewController over to my UIViewController to have it fulfill "Table data protocols" with UITableViewControllers default implementation and am following http://developer.apple.com/library/IOs/#documentation/UserExperience/Conceptual/TableView_iPhone/CreateConfigureTableView/CreateConfigureTableView.html#//apple_ref/doc/uid/TP40007451-CH6-SW10s chapter "Creating a Table View Programmatically" (with using ViewDidLoad instead of LoadView as I use IB and have a nib, I created an outlet for the UITableView named tableView).
Now in above links chapter the UITableView is assigned to self.view which is the UIView property of the UIViewController. Then scrolling the UITableView is working but the UITableView fills the entire screen hiding other view content such as an UIToolbar - probably as it is the sole content after being assigned to the view property.
If I omit the assignment, the other view content is in place an everything is sized properly, however the UITableView doesn't scroll.
How do I achieve scrolling of the UITableView inside an UIViewController with the UIVC having static content (such as a toolbar)?
Here's the relevant code:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
tableView.delegate = self;
tableView.dataSource = self;
[tableView reloadData];
//self.view = tableView;
}
If you have other content in the view controller that you are adding in interface builder then this will be part of the UIViewController's .view property - when you assign the table view to this, you are removing all that content.
If your table view is appearing normally but is not scrolling (how about selection? Does that work?) you may have disabled user interaction on it.
You have mentioned in comments that there is nothing but empty cells in your table view - I think this is the cause of your problem. I have just created a sample project where I have added in a table view as a subview of the view controller's view, and scrolling is fine - this is with me populating 100 dummy rows in there. If I don't return anything for the datasource and delegate methods, then the table view does not scroll.