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.