I have created a separate customView class containing collection view along with its Xib, and then i try to load this customView to one of the controller's view which is connected to a Tab Bar Controller. The view gets loaded perfectly but the last item of collection view is hidden behind the tab bar.
It would be great to have a solution for that.
My customView looks as
Try this
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let bottomOffset: CGFloat = (tabBarController?.tabBar.frame.height)! // this your tabbar height you can replace with static number eg. 44
collectionView?.contentInset = UIEdgeInsetsMake(0, 0, bottomOffset, 0)
}
Try to uncheck Under Bottom Bars..
It worked for me.
set
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
Related
I want navigationBar to overlap the root view of view controller, I have tried two methods:
self.additionalSafeAreaInsets = UIEdgeInsetsMake(-100, 0, 0, 0);
and
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
Neither of these options work.
So at the moment it looks like the figure below (The gradient orange is the navigationBar)View content below the navigationBar
However what I'd like to achieve is that the actual content of the viewController starts at the top of the screen and the gradient orange overlap the viewController.
If I still can not express it clearly, please tell me. Thank you.
Not sure what u meant but maybe:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(false, animated: false)
}
Or set it visible from the Storyboard
I have a custom UITableView with custom cells (70px height for each cell).
I have also a 49px UITabBar, but it's hides the tableView.
I've tried to add this line to the TableView awakeFromNib method but it didn't work:
self.commentsTableView.contentInset = UIEdgeInsetsMake(0, 0, 49, 0)
Any idea how can I solve this?
Thanks!
i don't know what you did exactly, but try like this:
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableview.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
I hope, this will work.
I ran into this issue when dealing with a table view in a navigation controller that did not have translucent bars. I performed a setup similar to the following:
override func viewDidLoad() {
super.viewDidLoad()
// Without this there is some extra fast inertia when slowly
// scrolling to the top.
extendedLayoutIncludesOpaqueBars = true
// Don't extend the tableview past the bottom bar, though.
// If we do then a tab bar or bottom nav bar will block
// content.
edgesForExtendedLayout = [.top, .left, .right]
}
However, I later discovered that a couple of checkboxes were unchecked in a storyboard higher up the hierarchy. Specifically these two:
Checking these two boxes removed the need to care about the content insets and the layout extending behavior in that view controller
This did the trick for me in Swift 3.
if let tabBarController = tabBarController {
self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, tabBarController.tabBar.frame.height, 0.0);
}
You should config the corresponding view controller with following code to remove the edges extend (It defaults to UIRectEdgeAll)
edgesForExtendedLayout = []
Try this
self.commentsTableView.contentInset = UIEdgeInsetsMake(49, 0, 0, 0)
self.commentsTableView.setContentOffset(CGPoint.init(x: 0, y: -49), animated: false)
If you changed self.hidesBottomBarWhenPushed=true in previous view controller, then make sure to change it to self.hidesBottomBarWhenPushed=false inside override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}
Try to use constraints for tableView and TabBar like:
In my navigation stack's child, I set edgesForExtendedLayout = .None
When I click the back button, the UITableView in my parent gets "moved up", as if the navigation bar doesn't exist. (The Navigation Bar covers the table).
Why does the child's edge setting affect its parent? I only want it to affect the current viewController.
In my parent, this is how I created the UITableView:
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.frame = CGRectMake(0, 0, screenWidth, CGRectGetMinY(self.tabBarController!.tabBar.frame))
self.tableView.addSubview(self.refreshControl)
self.tableView.tableFooterView = UIView(frame: CGRectZero)
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0
self.tableView.clipsToBounds = true
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
self.tableView.separatorColor = UIColor(hex: 0xededed)
self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
self.tableView.layoutMargins = UIEdgeInsetsZero
self.view.addSubview(self.tableView)
Could it be that I am setting the tableView's frame incorrectly? I want the table to start below the navigation bar, but end before the tab bar.
It sounds like this might be the correct behavior, but the opposite of what you are expecting.
edgesForExtendedLayout = .None means that the view controller's view will not extend under the top navigation bar or the bottom tab bar. You say that your child view controller is set to edgesForExtendedLayout = .None but not the parent view controller. And that when you go back to the parent view controller, the table view moves under the nav bar. If you did not set the parent view controller in your example to edgesForExtendedLayout = .None, then it will still be using the default of edgesForExtendedLayout = .All. And that will extend the top of the table view under the top and bottom bars.
For the behavior you are looking for, try setting edgesForExtendedLayout = .None on the parent view controller with the table view. So your parent view controller code could look something like this:
self.edgesForExtendedLayout = .None
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.frame = CGRectMake(0, 0, screenWidth, screenHeight - self.navigationController!.navigationBar.bounds.height - self.tabBarController!.tabBar.bounds.height)
UPDATE -- To implement the same result using auto layout (preferred over manual frames), first make sure that the table view is already added as a subview of the view controller's main view, then you can simply set up the constraints as follows:
tableView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
tableView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
tableView.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
tableView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
Using these NSLayoutAnchor convenience methods assumes iOS 9 or above. Of course an even easier approach would be to create the view controller in a Storyboard and just ctrl+drag the constraints in place. Either way, whether the constraints force the table view under the nav bar and tab bar or not will still be controlled by the view controller's edgesForExtendedLayout property. In a storyboard, you can control those setting by checking these different boxes in the inspector for the view controller:
I have UIViewController which extends UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout.
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
self.extendedLayoutIncludesOpaqueBars = true
}
UICollectionviewDelegate and DataSource methods aren't called, so UICollectionview appears to be empty. Even if I call reload data, DataSource methods still arent called.
When I delete last line, everything works fine except there is space below viewController.
edgesForExtendedLayout
Basically, with this property you set which sides of your view can be
extended to cover the whole screen. Imagine that you push a
UIViewController into a UINavigationController, when the view of that
view controller is laid out, it will start where the navigation bar
ends, but this property will set which sides of the view (top, left,
bottom, right) can be extended to fill the whole screen.
You need to set one of these two
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
OR
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = YES;
may be it will help you.
The structure:
View1 (click a button) -> present modally (MyModalView: UITableViewController)
MyModalView has UISearchController embedded. The searchBar of UISearchController is placed in MyModalView.tableView.tableHeaderView.
It's been working fine since iOS 8.0. However on iOS 9, the searchBar disappear when the UISearchController is active. Please take a look at theses pictures below
The modal view:
UISearchController active on iOS 8:
UISearchController active on iOS 9:
The very standard code:
override func viewDidLoad() {
super.viewDidLoad()
// Dynamically create a search controller using anonymous function
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
// Auto sizing row & cell height
self.tableView.estimatedRowHeight = 130
self.tableView.rowHeight = UITableViewAutomaticDimension
self.definesPresentationContext = true
// No footer for better presentation
self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}
This issue also happens in iOS 9.1 beta...
Any idea / pointer would be deeply appreciated
Cheers.
I'm not sure what exactly is the problem but I 'fixed' it by:
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.definesPresentationContext = NO;
My guess is that UISearchController is doing something funky when it is trying to present as a navigation bar. So, this is a hack but it at least doesn't block the user. The search bar doesn't do the cool animation and cover up the navigation bar.
It seems all of us got the same problem but they were solved in different ways. However none of the suggested answers worked for me :(. Nevertheless thank you all for your time.
I got a solution that solved my problem. It is setting Extend Edges - Under Opaque Bars of my (MyModalView: UITableViewController) to true in the Storyboard using Interface Builder.
In summary:
MyModalView: UITableViewController, in Storyboard using Interface Builder has
Extend Edges:
- Under Top Bars ticked
- Under Bottom Bars ticked
- Under Opaque Bars ticked
I found it's the simulated metrics (top bar) in storyboard that's cause this problem.
In my case, the following lines work, but I still don't know why.
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
I had to
self.aNavigationController?.extendedLayoutIncludesOpaqueBars = true
I found a similar question here but in my case it was not on the viewDidLoad method. I had to try different views until it worked. Now I can have both a custom navigation bar color and the search bar,
Thanks #wiles duan and #Techprimate
In my case, I fixed this issue by setting:
self.definesPresentationContext = NO;
And implement the following 2 methods in UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
I fixed it in my case by removing
definesPresentationContext = true
I didn't test yet if there are any disadvantages of removing this!
I had the same problem, and when I debugged the UI on Xcode I found that the UISearchBar view was moved to another view and the width was zeroed.
I fixed it by setting definesPresentationContext property of the UISearchController to false, and setting it true for the containing UITableViewController.
I added only one line to your viewDidLoad().
override func viewDidLoad() {
super.viewDidLoad()
// Dynamically create a search controller using anonymous function
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.definesPresentationContext = false // Disable the presentation controller
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
// Auto sizing row & cell height
self.tableView.estimatedRowHeight = 130
self.tableView.rowHeight = UITableViewAutomaticDimension
self.definesPresentationContext = true // This one remains the same
// No footer for better presentation
self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}
I don't have a navigation bar in this place of an app. None of other SO posts helped me, so I've fixed it this way:
- (void)layoutSubviews
{
[[[self searchController] searchBar] sizeToFit];
}
Setting the navigationBar permanently to translucent in storyboard solved my problem.
It works
override func viewDidLoad() {
super.viewDidLoad()
self.extendedLayoutIncludesOpaqueBars = !self.navigationController!.navigationBar.translucent
}
If you want to hide you navigation bar, and present search controller full screen, set the following on your navigation bar and search bar won't dissapper:
navigationController?.navigationBar.translucent = true
sc.hidesNavigationBarDuringPresentation = false
does the trick for me
lazy var searchController:UISearchController = {
let sc = UISearchController(searchResultsController: nil)
sc.searchResultsUpdater = self
sc.obscuresBackgroundDuringPresentation = false
sc.searchBar.placeholder = "Search"
sc.hidesNavigationBarDuringPresentation = false
return sc
}()
None of them worked for me, I fixed it using this hack
func position(for bar: UIBarPositioning) -> UIBarPosition {
if UIDevice.current.userInterfaceIdiom == .pad {
return .top
} else {
if iOSVersion <= 9 {
return .top
}
return .topAttached
}
}