Not able to position popover without the arrow - ios

I am displaying a popover (Present as Popover) as a dropdown when the user clicks on nav bar title (which is a label + an image). I was not able to set the nav bar title as popover's anchor view. So for anchor view, I added a clear 1x1 button that sits right below the nav bar (button.top = safe area.top)
I am able to position the popover along the y-axis by changing the y value in sourceRect.
popover?.sourceRect = CGRect(x: 0, y: -10, width: 1, height: 1)
It looks good, except I don't want the arrow in the popover. So I added this line of code.
popover?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
Now, I am not able to position the popover correctly. It doesn't matter what y value I specify in sourceRect, the popover stays at the same place.
What am I doing wrong?
Thanks.

The problem is that that is not how to suppress the arrow. The right way is to provide a custom UIPopoverBackgroundView that doesn’t draw the arrow.
However it would be better not to do this at all. Popovers have arrows. If you don’t want the arrow, don’t use a popover. Write a custom presented view controller instead.

Related

Static/fixed Navigation Bar in iOS

I have a Navigation Controller and a Collection View under it inside my app. And there is a problem: I use large title inside my Navigation bar, so everything inside is not static. When I scroll the collection view cells, the title (I created it manually using UILabel() to move it as I want inside the navigation bar) and buttons move up and the navigation bar takes form of iOS 10 navigation bar, I mean its height. You can see it here:
The normal state of my Navigation Bar with "Prefer large titles" On:
It happens when I scroll my Collection View, everything goes up:
So the question is simple: how to make the force constant height for the navigation bar? I want it to become fixed even while scrolling. Are there any ideas? Is it possible?
And the second question, if the first is impossible: Another solution for my problem is to make the Navigation Bar with "Prefer large titles" Off bigger. I tried this code:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let height: CGFloat = 50 //whatever height you want to add to the existing height
let bounds = self.navigationController!.navigationBar.bounds
self.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height + height)
}
but it worked only for large titles. So how can I make the navigation bar bigger?
Yes, you can make it fixed. It will not scroll if the very first view in the view hierarchy is not a CollectionView/TableView (ScrollView).
Using Storyboard/Xib:
Consider the following image where a tableView and button are added in scene. Here the navigation bar will collapse on scroll of tableView because tableView is the very first view in viewController's containerView hierarchy attached to the navigation bar.
Now to make the navigation bar fixed, if we just change the order of tableView and button as below, it will disable the collapsing of navigation bar.
To change the order of the view, you have to click, hold and move up/down.
If you have only CollectionView in this scene then you can add a placeholder view at the top and set its height to zero as below,
Programmatically:
If you are setting up view's programmatically then you just need to add a placeholder view at the top or add tableView/collection after adding other views.
e.g,
self.view.addSubview(UIView(frame: .zero))
self.view.addSubview(tableView) // or collectionView

Moving Tab Bar to the top of the screen swift

I want to have the Tab Bar at the top of the screen. One post suggested to do the followings (I put the following code in the viewDidLoad() of the UITabBarController) :
CODE
let tabBar = self.tabBar
// yStatusBar indicates the height of the status bar
let yStatusBar = UIApplication.sharedApplication().statusBarFrame.size.height
// Set the size and the position in the screen of the tab bar
tabBar.frame = CGRectMake(0, yStatusBar, tabBar.frame.size.width, tabBar.frame.size.height)
There are 2 problems with this solution:
The bottom of the screen is left with a black region where the tab bar was
The Tab bar covers the view at the top of the screen - the constraints of that view is relative to the device but they should be relative to the Tab bar. However when the screen is designed in the IB there is no Tab bar to relate to.
Is there a way to overcome these problems? P.S. I am new to IOS
let tabBar = self.tabBarController?.tabBar
// Set the size and the position in the screen of the tab bar
tabBar?.frame = CGRect(x: 0, y: self.view.frame.height, width: (tabBar?.frame.size.width)!, height: (tabBar?.frame.size.height)!)
Although it is against the human interface guidelines there exist a hack if you really want to.
You could create a blank UIView in your storyboard (with proper constraints set up) that would essentially be the placeholder for the tabBar when loaded.
You then set top constraints for your other views relative to this view that you have setup.
This works, but probably not best practice to do so

Drop Down Search Bar / View in Swift?

If I have a navigation bar, then a small (header) view, and then a table view, is there a way that I can have a search bar (when a bar button item is pressed) drop down I between the navigation bar and the view below?
I have tried just shifting the view between the navigation bar and table view down, but it just goes over the table view instead of pushing the table view down, or else it would work great.
Any help is appreciated! Sorry if anything is confusing just let me know if I can clarify anything.
If you want the search bar to "float" over the tableView on scroll, but when you scroll to the top of the list, then search bar doesn't overlap the tableView then you'll need to change the tableView's contentInsets to accommodate the search bar.
Something like:
tableView.contentInsets = UIEdgeInsets(x: 0.0, y: barView.bounds.size.height, 0.0, 0.0)
Then you'll need to scroll your tableView up to the top:
tableView.contentOffset = CGPoint(x: 0.0, y: -barView.bounds.size.height)

Hide tab bar causing incorrect UIView positions

In my view controller I have a UIView (drawer view) that sits below the visible screen with just the top poking out (a tab). This tab can be tapped and the UIView will animate up and fill most of the screen. The view is set like so:
drawerView = DrawerView(frame: CGRect(x: 0, y: UIScreen.mainScreen().bounds.size.height - DrawerView.submitTabHeight, width: UIScreen.mainScreen().bounds.size.width, height: UIScreen.mainScreen().bounds.height*0.75))
drawerView.delegate = self
view.addSubview(drawerView)
Below is a screenshot of the setup:
I have to present this view controller from a tab bar controller. I want to hide the tab when the view controller is loaded and I did this by setting Hide Bottom Bar on Push in the IB. The problem I have now is that when I push the view controller the drawer view is temporarily out of place. It is higher up than it should be by the height of the tab bar (shown by the dotted line on the screen). It then jumps back to the actual position it should be in. Any ideas what I might be doing wrong here? Any pointers on this would be greatly appreciated! Thanks
Just hide the tabbar before pushing the viewcontroller.
if (self.tabBarController) {
self.tabBarController!.tabBar.hidden = true;
}

UILabel misplaced after pushing to controller and setting hidesBottomBarWhenPushed

Having a bit of an issue with my tab bar app. I want to hide the bottom bar in the next controller I push to. I have set the hidesBottomBarWhenPushed to true in the IB. I have a UILabel pinned to the bottom of the screen in this controller. When I push to it the label is not at the bottom of the screen but above it at the same height the toolbar was. Any ideas what I might be doing wrong here? Any pointers would be great!
Not the cleanest of solutions, but you could rearrange the label when the BottomBar gets hidden
Like this:
label.frame = CGRect(x: label.frame.origin.x, y: label.frame.origin.y + 'tabbarHeight', width: label.frame.width, height: label.frame.height)
You would just have to add the height of your tabBar to the y value
Edit: This is also reversible, so when you are navigating back, just subtract the tabBarHeight from the y value

Resources