I am experimenting with Xcode 6 and Swift and having a little issue with the Interface Builder.
I created a new scene by dragging a TableViewController which comes with a TableView however when run it on a simulator the top cell is far too close to the top, it almost touches the central Date and Carrier logo.
As this seems to be a root view, I cannot add constraints, I also cannot find a way to adjust so that I have a margin that is flexible / responsive to different screen size.
You don't want to try to constrain the table to underneath the status bar, as this will cause the content of the scroll view to magically vanish as it goes above the 20pt mark. Instead, allow it to continue to be full screen and simply set the table's contentInset property (More info in documentation).
This will cause the table to scroll as it normally would with the content going out the top of the screen, with the added ability to come to rest just under the status bar.
let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
tableView.contentInset = UIEdgeInsetsMake(statusBarHeight, 0.0, 0.0, 0.0)
Related
in iOS 13 it happens that the view of UIViewcontroller that is presented as model starts from the tip of the arrow. Because of it top banners in all of my popover gets cut. Can I prevent this from happening ? I want that my UIView does not start from arrow but once arrow is finished.
To fix this issue, I opened up my view controller's XIB, selected the top-most view, and then checked "Use Safe Area Layout Guides" under the File Inspector. Then I added Auto Layout constraints (of length 0) around that view's sole subview (a UITableView).
(I also needed to update the view controller's background colour. This changed the arrow colour back to what it was in iOS 12 and before.)
Background: https://forums.developer.apple.com/thread/122703
I wonder if your contentView contains UIScrollView. If yes, please add alwaysBounceVertical = YES to your scrollView. It works in my case.
I don't know why they changed this behavior, it can be a pita to deal with it if you are not using xibs. I couldn't find anything in the docs about it.
Use the safe areas to adjust the position of your view. You can both try to extend the size of that red area, or skip the arrow completely. In this particular case you can use safeAreaInsets.top if the arrow is going to be on the top always.
I want to have Buttons hidden above my normal content in the ScrollView, which will appear when I swipe down. Currently, I have these Buttons in a StackView inside the ScrollView. I want the view to snap between two positions where the Buttons are not visible and where they are, but also, I may need to scroll if the actual content is larger than the screen.
I've tried contentOffset. This works at first, but then if it is scrolled and the content is smaller than the screen, it will always show the Buttons.
Any ideas on how to do this?
Image for clarification:
It's hard to understand what you describe. But as my imagination what you need is set contentInset for scrollview with negative Top value, like this:
UIScrollview.contentInset = UIEdgeInsetsMake(-60.0, 0.0, 0.0, 0.0)
My headerView in my tableView should go all the way to the top of the device. On iPhone X the same so the notch goes over it.
Then when I scroll my tableView I use scrollViewDidScroll(scrollView: UIScrollView) to change the height of my headerView to add scrollView.contentOffset.y so it goes all the way.
It works as soon as I scroll but not initially.
So it looks like this:
and this on the X
How to I get rid of the white area so the grey one goes under it when it loads?
I tried a couple places but it seems the tableView still has no contentOffsets... I think I am missing something fundamental here how "it should be done"...
Update: ViewHierarchy, blue is tablewView, but then I get this distance there...
Ok I found it. So it has to do with the change with safe areas introduced for the iPhone X.
There are two possibilities, it really depends on the storyboard setup:
If you are using a storyboard and your base is a UIViewController with a tableView placed inside it:
Then fixing the auto layout is the answer:
When safe area is enabled, click on your topmost view and create the top constraint is relative to the superView with constant 0. By default it wants to protect the safe area so it is set relative to the safe area.
If you are using a UITableViewController template (e.g. default when dragging out a navigation controller - tableview combo (my case))
Here there are no constraints that can be set. Hence it didn't work for me (see above).
To fix it click on the root tableView, select the size inspector and then set "content insets" to "never".
Or programmatically in viewDidLoad:
self.tableView.contentInsetAdjustmentBehavior = .never
Are you making your tableview in storyboard?
in viewDidLoad try anchoring your tableview:
tableview.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
The alignment of our table is working well except of the top alignment of the top cell which bleeds into the "carrier area". What is required to address this?
We're using self sizing cells:
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
Overview of the current constraints:
Basically Apple doesn't want you to do what you're doing. Look at Apple's apps (Settings, Mail, etc.). You will never see a full-screen table view without a navigation bar at the top. So imitate that. Instead of fighting the framework, wrap your view controller in a UINavigationController and let the navigation bar push the top of the table view down for you automatically.
Normally when you use a navigation controller to wrap the view controller, TopLayoutGuide (and BottomLayoutGuide will be set for you and with "Adjust Scroll View Insets" that you can set in the storyboard file, it will automatically set contentInsets of the outermost scrollview for you to accommodate that. But since you don't use a navigation controller to wrap your view controller here, you have like three options.
1. Manually set the frame of the table view to offset for the status bar's height.
We just move the table view down 20 points and make it 20 points shorter. The ideal place is somewhere in your code we know it will be called every time the superview's bound is changed. One of them is in viewDidLayoutSubviews.
Try putting this code in your view controller's code.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.superview!.backgroundColor = UIColor.whiteColor()
let insets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
self.view.frame = UIEdgeInsetsInsetRect(self.view.superview!.bounds, insets)
}
Please note that I have to set the background color of the superview's to white because the superview (which is likely to be UIWindow) might have no background color and it will make the top part appears black. And normally in the production code, you might want to check whether the superview's bound has really changed before setting the frame.
2. Use UIViewController and add UITableView as subview.
This way Interface Builder will allow you to set the constraints all you want.
3. Just wrap this with UINavigationController
And it will appear like most apps that have a navigation bar on the top. This might not be what you want. But I rarely see a table view without wrapping by a navigation controller.
Select your table view. In the bottom right side of your screen (left of where you drag the objects to the screen) you will see 4 small buttons. If you click on the 2nd to the right (a square with 2 lines to it's sides) you will see a small sub-menu saying Add new constraints. Below it you have a square with 4 values (top-right-bottom-left). Make sure the top one is 0 and then click the semi-transparent dotted red line. It should become solid red. Now just click the "Add constraints" button at the bottom and you are done.
Hi I have set in my storyboard a UIScrollView (of the same size of the view) and ctrl-dragged it in my code.
Now I have created a button programmatically using a simple algorithm of mine.
I then tried to
println(button.frame.origin.y)
which printed 1700.
Then I tried
println(button.frame.height)
which printed 142.2 (also coming from the algorithm). So the heigh I would like to reach while scrolling is 1700 + 142.2 = 1842.2
So i tried to hardcode the content size in this way
self.scrollView.contentSize = CGSize(width:self.view.bounds.size.width, height:2000)
But when I run the app I can scroll no more than the middle of the button, which is in numbers
1700 + 142.2/2 = 1771.1
Why the heck is that?
I did all this to try to understand how this UIScrollView works but I can't figure it out.
EDIT
Added a screenshot.
Inside the bubbles there is the button.frame.origin.y value. That's the max I can scroll leaving the screen untouched.
This is probably to do with scroll view insets - a mechanism where the edges of the content always appear under the navigation and toolbar.
You either need to manually account for this by reading the contentInset property of the scroll view, or using interface builder.
Scroll view Reference:
https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/UIScrollView_pg/CreatingBasicScrollViews/CreatingBasicScrollViews.html