How does the ScrollView.scrollIndicatorInsets actually work ?
If you set all insets to 0 as default, and you do some debugging you will actually find that the scrollbar isn't exactly near the bottom or right edges by default as it should be.
ScrollView.scrollIndicatorInsets = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)
As you can see, there is some extra spacing between the scrollbar and the scroll view edges.
Is there any way that I can place the scrollbar bottom left corner exactly at the bottom left corner of the view programatically ? I don't want to hardcode anything, I want it to work on any scrollview size and screen.
What do the insets actually specify (yes, I know they specify a rectangle for the scrollbar) ? Is there a default spacing-to-edge that iOS uses for the scrollbar and I have to take that into consideration ? Is there glow on the scrollbar's layer view, hence the spacing ?
EDIT:
I solved this using the non-convential approach by accessing the UIView from the scrollbar itself (subviews.last), and using the smallest size (which is the thickness).
Quick inspection shows the Scroll Indicators with Insets set to UIEdgeInsetsZero (the default) places them 3-pts from the edges.
You can try using:
theScrollView.scrollIndicatorInsets = UIEdgeInsets.init(top: -3, left: -3, bottom: -3, right: -3)
which should align the horizontal indicator flush to the bottom, and flush with the left and right edges, and the vertical indicator flush to the right, and flush with the top and bottom edges.
You might want to get the frame(s) first though, as it's possible it varies between devices / sizes / iOS versions.
Edit:
A couple clarifying notes...
The scroll indicators are image views. You can find them by inspecting the scroll view's subviews (code or with Debug View Hierarchy).
The default insets (of Zero) put those image views 3-pts from the edge of the scroll view's frame.
With a 300 x 500 scroll view, the origin of the vertical indicator is:
x:294.5 y:3.0 with a width of 2.5
294.5 + 2.5 == 297
// 3-pts from the right edge, 3-pts from the top
and the origin of the horizontal indicator is:
x:3.0 y:494.5 with a height of 2.5
494.5 + 2.5 == 497
// 3-pts from the left edge, 3-pts from the bottom
So, using:
.scrollIndicatorInsets = UIEdgeInsets.init(top: -3, left: -3, bottom: -3, right: -3)
moves the origins to
// vertical
x:297.5 y:0.0 with a width of 2.5
297.5 + 2.5 == 300
// flush to top and right edges
// horizontal
x:0.0 y:497.5 with a height of 2.5
497.5 + 2.5 == 500
// flush to left and bottom edges
I suppose it's possible that could change in the future. As fewer and fewer people use devices with small screens, Apple could change the width/height to 3 or 3.5 or whatever, and could change the default inset from 3 to something else. Which is why I said you might want to get the frames to get the proper inset values, rather than hard-coding them to 3.
Curiously, though, until the indicator frames have been drawn to the screen - either by flashing them or actually scrolling the content - their frames are set to 7-pts in height (for the vertical indicator) and 7-pts width (for the horizontal), and positioned at the bottom-right corner.
So, with the 500 x 300 scroll view frame, the indicator frames are initially:
// vertical
x:294.5 y:490.0 w:2.5 h:7.0
// horizontal
x:290.0 y:494.5 w:7.0 h:2.5
That still tells you they are 3-pts from the edges, but it's not quite as clear... and again, no guarantee that won't change in the future.
If you really want sure the indicators will go where you want them, your best bet may be to use custom views instead of the built-in indicators.
Related
I have a UIButton with title "⟳". The title does not appear to be vertically centered due to the position of "⟳".
I understand that offsets of the UIButton can be changed to solve the problem in this instance.
Can anyone point out if there is any other way to vertically center the "⟳" glyph?
In this image, all 4 green buttons are using 64-pt System font, with the .titleLabel background set to yellow:
As you can see with the top button, an upper-case "O" is centered vertically and horizontally.
The "⟳" unicode symbol you are using is more like a lower-case character - as seen in the 2nd button.
By itself, in the 3rd button, we see it appears "shifted" down and to the left.
The symbol in the bottom button is center-aligned by adjusting the Title Edge Insets:
.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 14, right: 0)
So I have a label that I've made in Xcode's storyboard which I want to later edit in my code. I want it to simulate something like a vertical bar so I am editing its height by doing:
answerE.frame.size.height = -200
The problem comes from the negative number, I want the label to "grow" up so the height has to be negative from its original position... I have the line in code in a simple action on button press, but each time the line is executed the label moves "up" and eventually after 3-4 clicks is out of the screen.
I just want to edit its height, what is the correct way and what am I doing wrong?
My exact line in code is:
label.frame.size.height = -CGFloat(Double(x)/Double(y) * (200))
If you have added the label in storyboard, why not you use constraints to get the result.
Add leading, trailing , bottom and fixed height constraint and connect IBOutlet to height constraint. Change the constant value of height constraint at the event which you want to perform.
If I'm right, you want the label to gain height, keeping the same bottom edge, but the top edge moving up.
In order to do this, you want to change the frame.origin.y as you change the frame.size.height at the same amount, as its placement (and so top edge) is determined by its origin. So maybe make it zero height, place it where you want it in storyboard, and then when you want it to 'grow' by x:
label.frame.size.height = label.frame.height + x
label.frame.origin.y = label.frame.origin.y - x
I have read the Human Interface Guidelines for iPhone X and it doesn't specifically state the 'safe region' (area which caters for both top notch and bottom bar on the iPhone X). I would like to know the pixel dimensions of this region, including the dimensions removed from the top and bottom.
In Portrait
Top: 44pt
Bottom: 34pt
Left/Right: 0pt
In Landscape
Top: 0pt
Bottom: 21pt
Left/Right: 44pt
By printing the safe area insets of the current window with the following code, you can get the point dimensions of the top and bottom safe area.
if #available(iOS 11.0, *) {
UIApplication.shared.keyWindow?.safeAreaInsets
// ...
}
In portrait, the top area is 44 points long and the bottom area is 34 points in length.
Since iPhone X has a #3x resolution, the top area is 132 pixels long and the bottom area is 102 pixels in length.
Xcode 9 introduced safe-area layout guides into the interface builder. You can turn them on by going into your storyboard's file inspector and ticking the checkbox labelled "Use Safe Area Layout Guides"
From there whenever you add constraints to your root view, you get the option of constraining it to the safe area instead. In this photo, the view in orange is constrained to the edges of the safe area while the view in blue is constrained to the edges of the superview.
Orange view's frame: (0.0, 44.0, 375.0, 734.0)
Blue view's frame: (0.0, 0.0, 375.0, 812.0)
From there we can calculate that 44 points were used for the top safe area while 34 points were used for the bottom area.
You can get it from safeAreaInsets property of a view in a UIViewController.
You don't need to call the singleton UIApplication, can get them also from your view layout.
self.view.safeAreaInstes. (top,bottom,left.right)
Okay so I am new to the Swift programmming language and IOS platform however I have a strong background in mobile development on other platforms such as Android/WP/Xamarin so I decided to just dive in and learn the layout system starting with Auto Layout.
Here I am trying to center a view horizontally and align it to the bottom of the screen using the Auto Layout API via PureLayout. When I set the view to align to the horizontal axis of it's superview this is result I get.
Code
override func updateViewConstraints() {
if(!didSetupConstraints)
{
blackView.autoPinToBottomLayoutGuideOfViewController(self, withInset: 10)
blackView.autoSetDimensionsToSize(CGSize(width:50,height: 50))
blackView.autoAlignAxisToSuperviewAxis(.Horizontal)
didSetupConstraints=true
}
super.updateViewConstraints()
}
Result
However when I set the view to align to the vertical axis I get the desired end result
Code
override func updateViewConstraints() {
if(!didSetupConstraints)
{
blackView.autoPinToBottomLayoutGuideOfViewController(self, withInset: 10)
blackView.autoSetDimensionsToSize(CGSize(width:50,height: 50))
blackView.autoAlignAxisToSuperviewAxis(.Vertical)
didSetupConstraints=true
}
super.updateViewConstraints()
}
Result
Even though I got the result that I wanted, I did not feel good about proceeding without properly understanding why it got aligned in the center horizontally by setting the view to align to it's superview's vertical axis. So can someone explain to me the whole notion of aligning to axes and how they work in Auto Layout. Thanks in advance.
Being centered horizontally and aligning to the vertical axis are the same thing.
The vertical axis is a imaginary vertical line that is centered between the views left and right edge. So if a view is aligned with it, the view will be positioned anywhere along that vertical line, causing the view to be entered horizontally.
The source for Pure Layout also has a definition and shows how they map to regular auto layout if that helps.
/** A vertical line equidistant from the view's left and right edges. */
ALAxisVertical = NSLayoutAttributeCenterX,
/** A horizontal line equidistant from the view's top and bottom edges. */
ALAxisHorizontal = NSLayoutAttributeCenterY,
I'm new to Swift and ios development. I have 6 labels and a horizontal SKScene in my App. I would like to align those 6 labels beautifully and automatically. Now I have fixed the positions and the alignment always looks awful on some screen size while good on other.
I have not used storyboards or other graphical editors for building the ui but everything is done in code. Therefore I'm looking for a programmatic solution (code examples) for handling the alignment.
If you want to place them in the middle of the screen horizontally, but give them different y positions, you could just do something like this for each label:
label.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMaxY(self.frame) * 0.80)
To place them at different y positions, just multiply by the maxY by a different decimal number. This way, all of the labels are aligned along the x-axis and appear at different y-positions, like a column and they will appear this way on every screen size because they are positioned relative to the screen size and not in a fixed position.
You can align the labels (lets say at the center of the screen) like this.
var label1 = UILabel(CGRectMake: 0, 0, 200, 40)
label1.center = CGPointMake(UIScreen.mainScreen().bounds.size.width/2, 30)
var label2 = UILabel(CGRectMake: 0, 0, 200, 40)
label2.center = CGPointMake(UIScreen.mainScreen().bounds.size.width/2, label1.center.y + 30)
and so on. Just reference the main screen bounds and not static points for alignment, so that they are centered in any screen size.
What I ended up doing was to create an empty SKSprite to which I included the SKLabels. Now I can control by the pixed the distances between labels but align the top-level sprite in the middle of the screen despite screen size.