I have a scroll view with the constraints:
equal width to Safe Area
equal height to Safe Area
Align Center X to Superview
Align Center Y to Superview
It contains only a vertical Stack View with the following constraints:
Align Center X to: SuperView
Proportional Width to Superview (multiplier 0.9)
Top Space to Superview: 0
Now, if I add enough items to the stack view, so that it exceeds the bottom of the Scrollview, I can't scroll it. Why is that so and how can I make it work?
here is my storyboard:
https://drive.google.com/file/d/1TZHl3d_HCptqx8ezcOpNJjH8RSitOln5/view?usp=sharing
Related
I'm looking at drawing a custom theme element onto a device content.
For example's sake, i will use the HeaderItem from the Windows XP header/listview:
(18×18 px)
Which we can blow up to see a little easier:
Note: I am not using the Theme API, nor am i asking about using the Theme API.
If i have my bitmap, like the one above, how can i draw it in practice?
Stretch draw ruins the style
The important problem that needs solving is how to maintain the important details. You can see the actual Windows XP Header draws the right-edge vertical line nice and crisp:
But if i were to blindly StretchBlt the image, the details become fuzzy:
The issue also happens with theme elements with crisp horizontal feature when the image is stretched vertically. In this case it also messes up the vertical gradient. But some other element have it even more pronounced.
So what is the technique that can be used to address this?
Should i cut 6 px off the top, left, bottom, and right?:
And then rather than drawing 1 image, i draw nine?:
And draw them with various horizontal or vertical stretch rules depending where it is?:
Unstretched
Horizontally stretched
Unstretched
Vertically stretched
Horizontally and vertically stretched
Vertically stretched
Unstretched
Horizontally stretched
Unstretched
This must be a solved problem already; since Windows already solved it, and who knows how many more Widget libraries that support themes.
Microsoft's solution to this problem can be reverse engineered by looking at the NormalBlue.ini file inside Luna.msstyles. Looking at the entry for Header.HeaderItem:
NormalBlue.ini:
[Header.HeaderItem]
bgtype = imagefile
SizingMargins = 8, 8, 3, 4
ContentMargins = 3, 0, 0, 0
ImageFile = Blue\ListViewHeader.bmp
imageCount=5
imageLayout=vertical
sizingType = tile
transparent=true
transparentcolor=255 0 0
FillColorHint = 250 248 243; Average fill color (light beige)
AccentColorHint = 252 194 71; Rollover hilite color (orange)
First we see it references the \Blue\ListViewHeader.bmp:
ImageFile = Blue\ListViewHeader.bmp
Which is:
And then there's the magic piece:
SizingMargins = 8, 8, 3, 4
This corresponds to TMT_SIZINGMARGINS:
TMT_SIZINGMARGINS: The margins used for sizing a non-true-size image.
where you can see some more hints in TmSchema.h:
//---- rendering MARGIN properties ----
TM_PROP(3601, TMT, SIZINGMARGINS, MARGINS) // margins used for 9-grid sizing
"Margins used for 9-grid sizing". This is a reference to the idea that you split up the image into 3x3 grid, and size the chunks independently as appropriate.
And the final piece is the documentation of the MARGINS type in UxTheme.h:
typedef struct _MARGINS
{
int cxLeftWidth; // width of left border that retains its size
int cxRightWidth; // width of right border that retains its size
int cyTopHeight; // height of top border that retains its size
int cyBottomHeight; // height of bottom border that retains its size
} MARGINS, *PMARGINS;
and its documentation:
cxLeftWidth: int - Width of the left border that retains its size.
cxRightWidth: int - Width of the right border that retains its size.
cyTopHeight: int - Height of the top border that retains its size.
cyBottomHeight: int - Height of the bottom border that retains its size.
Chop and Paint
The Luna theme is telling us that when we draw ListViewHeader.bmp, we need to use the sizing margins:
SizingMargins = 8, 8, 3, 4
And cut the image up into 9 pieces (3x3). But rather than using 6px all around (like i said in my question), we need to use the sizes that the designer of the image intended:
Left: 8
Right: 8
Top: 3
Bottom: 4
So given the 18×18 theme element image created in Photoshop by a designer:
The person who created the image said that my drawing code needs to cut off:
left 8 pixels
right 8 pixels
top 3 pixels
bottom 4 pixels
Meaning i then have to draw each of the nine images:
And then stretch draw some parts in certain directions:
Top-left: draw unstretched
Left: stretch vertically
Bottom-left: draw unstretched
Top: draw stretch horizontally
Middle: draw stretched horizontally and vertically
Bottom: draw stretched horizontally
Top-right: draw unstretched
Right: draw stretched vertically
Bottom-right: draw unstretched
I have 2 UILabels side by side. The one on the right grows as the content inside changes (using sizeToFit) and when it grows, the one on the left should shrink and truncate if needed.
Here are the current constraints I have:
The left label:
Leading space to superview: 8
Width <= 156
Top space to superview: 0
Height: 32
Trailing space to right label: 8
The right label:
Trailing space to superview: 8
Width >= 0
Top space to superview: 0
Height: 32
Leading space to left label: 8
Leading space to superview <= 172
Using what I have here the right label will grow as it should, but the left label will not shrink and truncate the text inside. What am I doing wrong?
Edit: Both labels should have a static height. The right labels width should grow and the left labels width should shrink.
For growing and shrink constraints each UIView have this methods:
contentCompressionResistancePriorityForAxis:// For setup shrink constraints
contentHuggingPriorityForAxis:// For setup growing constraints
Don't forget of priority.
p.s. Storyboards have same fields in params for each view.
In InterfaceBuilder, is there a way to add an
Align Center Y to
constraint? I can't find this type of constraint anywhere and I'm not sure how to create it by control + drag.
Align center Y to` = Center Vertically
Align center X to = Center Horizontally.
Press control on your element, hold it and link it to an other element, select Center ....
I have 4 buttons in an row, how can i align this in the middle on each device? iphone 4s, iphone 5s, iphone 6, iphone 6 plus.
Only on the iphone 6 it looks good. On the iphone 4s the buttons going outside the view and on the 5s and 6 plus is it not centered.
On the left view you see the layout, and the right view you see an preview.
How can i fix this issue? I have tried auto layout but this doesn't work..
Here with the constraint alignment (horizontal) on each button. But they are not in the middle..
thank you.
To align multiple buttons in the center of the canvas, you can place two "dummy" or "helper" views on each side. Then apply the following constraints:
equal width for the two dummy views.
leading space to superview = 0 for the left dummy view.
trailing space to superview = 0 for the right dummy view.
horizontal spacing = 0 for the dummy view and the button.
horizontal spacing = some fixed value for the buttons.
You can set the dummy view's height to 0.
Below is an example in the storyboard. For the sake of simplicity, I only included two buttons. You can have as many buttons as you like using this method.
I might be missing something here. But is it all that you need, to have multiple buttons centered vertically in the container and also horizontally (with no overlap and good symmetry). If so, you can do the below.
The constraints are -
Button A - Center vertically in container
Button B:Center Y = Button A:Center Y; Button C:Center Y = Button B:Center Y
Button A: Leading space to superview = some constant (say 30)
Button C: Trailing space to superview = same constant as above
Horizontal spacing (Button A - Button B) = Horizontal spacing (Button B - Button C) = some constant (say 10)
Width (Button A) = Width (Button B) = Width (Button C)
What I want to achieve:
Custom View 1
aligned at the top
fixed height = 20px
width = window width
Horizontal Split View
just below the custom view
width = window width
height = as large as possible
Custom View 2
aligned at the bottom
fixed height = 20px
width = window width
It's a really simple layout: a header and a footer at the top and bottom of the window, and a split view in between with some content to the left and to the right that should resize with the window. However, Apple designed the Auto Layout manager so poorly, I can't seem to get this to work. (I've fumbled around for about three hours now!)
The problem is: As soon as I give the custom views a fixed height, the window height is locked, I can't resize it vertically any more. I'm trying to do this with the following constraints:
Custom View 1
Constraints
height = 20px
Custom View 2
height = 20px
Constraints
Leading horiz space from Custom View 1 to Superview = 0
Leading horiz space from Custom View 2 to Superview = 0
Leading horiz space from Split View to Superview = 0
Trailing horiz space from Custom View 1 to Superview = 0
Trailing horiz space from Custom View 2 to Superview = 0
Trailing horiz space from Split View to Superview = 0
Top vert space between Custom View 1 and Superview = 0
Vert space between Custom View 1 and Split View = 0
Vert space between Custom View 2 and Split View = 0
Bottom vert space between Custom View 2 and Superview = 0
Top vert space between Custom View 2 and Superview = 344px (!)
The last line is added by Xcode, and I can't delete it. Of course, this is responsible for the fixed vertical layout. How can I get rid of it???
OK, I finally figured it out.
I had to leave IB's redundant constraint in, but give it a priority of 1. IB had given it a priority of 1000, always overriding my constraint.
Every view needs to have enough constraints for the layout system to calculate the position (x and y) and the size (width and height). If the system does not have enough information to calculate these properties, the layout is considered ambiguous. Interface Builder in Xcode will not let you create an ambiguous layout, so it will add constraint to ensure a fully constrained layout.
Based on your information, it seems as though subview2 is sufficiently constrained. However, I think maybe you haven't set the height of the view as a constraint. The frame you set for a view is ignored by the layout system. That would introduce ambiguity. Try adding a height constraint to subview2.