My aim is to have 3 images shrink, grow, and move along a horizontal axis depending on selection. Using Auto Layout seems to make the images jump about as they try to fulfil the Top space to superview / Bottom space to superview constraints.
So to combat this I have put all the images inside their own UIView. The UIView is set to the maximum size the images can grow to, it is centred on the horizontal axis. So now all the images must do is stay centred inside their corresponding UIView. This has fixed my problem as the UIViews perform the horizontal translation, while the images shrink/grow inside while remaining centred. My question is - is this the correct way to do this? It seems very long and like I am perhaps misusing the ability of Auto Layout. I have to perform similar tasks with more images and so any advice is welcome! Thanks.
I've just written a little essay on this topic here:
How do I adjust the anchor point of a CALayer, when Auto Layout is being used?
Basically autolayout does not play at all well with any kind of view transform. The easiest solution is to take your view out of autolayout's control altogether, but alternatively you can give it only constraints that won't fight back against the particular kind of transform you intend to apply. That second solution sounds like just the sort of thing you're doing.
Related
I'm working on a view that's implementing a multi-column text layout using CoreText (using CTFramesetter).
CoreText usually fills each frame completely, so when I call CTFramesetterCreateFrame with three rects that make up my columns, I get a layout that's similar to the following image:
So the left column is filled completely, the middle column partially and the right column is empty. But instead, I'd like the text to distribute over the three columns so that they take up the least vertical space possible, like in this image:
How to achieve this with CoreText?
I don't mind going low-level here, even drawing each CTRun by hand is an option if necessary.
One idea I came up with would be to create a large frame with the width of a column and then figure out which CTLine to draw in which column. But this has a few limitations:
It would only work if all columns had the same width.
It does not work with clipping paths.
Unfortunately, I'll need to use clipping paths (as in kCTFrameClippingPathsAttributeName) so this idea is out. I could live the fixed column width limitation, though.
Another idea would be to reduce the height until the last frame overflows but that's a pretty brute-force way that surely wastes resources.
(BTW, due to compability requirements the use of TextKit classes like NSTextStorage isn't possible; the resulting view is intended to be used on Mac and iOS, but it needs to work on iOS < 7)
Since there doesn't seem to be a non-expensive way to solve this, here's how I've done it:
I did go with the "reduce the height until the last frame overflows" approach. To reduce the height, I simply have another clipping path (kCTFrameClippingPathsAttributeName) which is a rectangle that fills the bottom of the view to the required height.
The probably most expensive but simple way would have been to increase the rectangle height until finally the text doesn't fit inside the last frame any more.
Instead I've implemented a binary search for that. For my demo app, I usually find the correct height after 8-10 recursions which still is expensive but at least it's pixel-perfect and doesn't rely on any other information other than "did the last frame overflow".
Since it's a bit difficult to explain, I did a mockup to get across as much as possible visually:
http://sassmeister.com/gist/70624a740b1ca4ae7764
(If there's a better way to share a sass gist, let me know. First time using it)
Basically, this is the layout I want for a tablet in landscape mode. What I'm trying to do is make sure it fits perfectly on different tablets with different aspect ratios. Some things are fixed. The main content area is a 16x9 video, so that aspect is locked.
I have the header and footer (main column only) fixed right now as they need to be for portrait mode, but I could bring them into the regular flow if it's helpful for tablet landscape. Anyway, it's all basic responsive right now via susy2, and the sidebar is totally separate so it can scroll independent of the main content. What I would like is for the whole main area including header and footer to fit perfectly with even margins above and below vid, but then have the sidebar column change it's width to match the tablet.
So... if the tablet is wider, the teaser thumbnails go out to 16x9 ratio. If the tablet is narrower, the main column remains unchanged, but the teaser thumbs narrow down to squares.
If it's easier first to just figure out how to responsively shrink the right column only, so the aspect of thumbs is unchanged, that's ok. I just don't want the overall layout to get screwed up on one device vs another because of aspect ratio, so main focus is that the header hits top, footer hits bottom, main vid fits perfectly between them, then sidebar responds to fill in the rest (within reason).
thx for any input. First time making a website here, so lots to learn.
ps. I had vertical scroll enabled for the right column, but disabled it (by adding extra letter to to the scrolling class in scss column) since it's not actually letting me scroll. Not sure if that's because there's no actual content, or it doesn't recognize the empty padded cells as something worthy of scrolling.
You're biting off a lot for your first website, but Sassmeister is a great way to show what you are doing. I approve. :)
One of the problems you'll find is that CSS don't have the concept of aspect ratio built in, so the sort of layout you are attempting is non-trivial. CSS is best at handling widths, and letting everything overflow vertically. It takes some effort to make it handle height well.
If you can get away with it (depending on browser support), your best option is to use flexbox. Flexbox should make this much easier, but doesn't ave a lot of support yet. You could consider table-cells, which have more support, but can be harder to control.
In any case, you should ignore most of Susy for this — at least in laying out the large sections. If you want Susy to help you with grid calculations, ditch the mixins and just use the span() and gutter() functions to help you set widths. Something like this:
.flexbox {
flex: 1;
flex-basis: span(3);
}
.tables {
display: table-cell;
width: span(3);
}
// NOT THIS
.no {
#include span(3);
}
You can go back to using Susy mixins for simpler bits, like the items in the top navigation.
I need to display many markers on a WPF image. The markers can be lines, circles, squares, etc. and there can be several hundreds of them.
Both the image source and the markers data are updated every few seconds. The markers are associated with specific pixels on the image and their size should be absolute in relation to the screen (i.e. when I move the image the markers should move along with it, but if i zoom in, they should take the same space of the screen as before).
Currently, I've implemented this using the AdornerLayer. This solution has several problems but the most significant one is that the UI doesn't fare well under the load even for 120 such markers.
I wanted to ask what would be the best way to go about implementing this? I thought of two solutions:
Inherit from Canvas and make sure it is invalidated not for every
added marker but for a range of markers at once
Create a control that holds an image and change its OnDraw to draw all the markers
I would appreciate some pointers from someone with experience with a similar problem.
Your use case looks quite specialized, so a specialized solution seems in order. I'd try a variant of your second option — extend Image, overriding its OnRender method.
Given a WPF Application running full screen, a fair amount of controls some of which will animate from off screen to center. I was wondering if there are any special ways to save on the amount of time required to optimize an application for different screen resolutions?
For example, using Blend I've setup some text, which is originally off screen to scroll into view. Now in design mode the start positions are static. If resolution changes the start positions will obviously not be correct.
So I guess to correct this, during app startup. I need to
Check resolution
Move the text box to the desired start location
Adjust the storyboard as required, so the frames all have correct co-ordinates depending on the res of the screen.
I don't mind doing all of this, but if there is an easier way please share!
Thanks
In WPF layout of controls should be made in such way, that when size of window or content changes, controls automaticaly resize/reposition themselves to reflect this change.
This is highly affected how your layout is made, especialy by using specific panels, that do layout of their child elements.
This is also made obvious by using device-independent units for sizes, margins and sometimes positions of controls. And also allows different kind of zooming and scaling of whole UI without any need to redesign the whole thing.
If you are trying to position your controls absolutely, either by using Canvas panel or margins, your are doing it totaly wrong.
In WPF, scene is measured in abstract units, not pixels, and controls are freely scaled. There should be no problems to center something, or what?
How should I develop a form that can resize nicely?
While that sounds like a simple question the problem I'm struggling with is the fact I'm reproducing an existing application I made in Swing several years back. Its built around a single form that hides/reveals panels as you select different options.
Its around 600 x 700 pixels wide say but its a fixed size window.
Is this good practice? The GUI works fine this way but if you look at other applications you can resize them easily. Granted some applications look stupid full size but should the option be there?
The main screen consists of about five buttons, when maximized this looks ridicilous, but at the same time if the form is resizable the moment you start resizing the form it becomes stupid.
I'm aware of layout managers and so forth so no need to tell me to check these out, my main problem is the fact I can produce an excellent fixed width application but that's about it.
Any advice/links for this?
Personally, I think fixed size forms are a horrible User Experience.
I always try to build mine so that they can be gracefully resized (even if they do look a little odd).
If you're using .NET for your WinForms development, you can easily use a table layout and then anchor your controls so that they resize politely.
A fixed size gui is generally a bad idea because most forms have a user interface element that can sensibly be resized.
First consider a form that only contains two buttons. (A silly form, yeah, but for the sake of discussion we'll assume that it's the right thing for the job) When sized initially in the right way (appropriately for localization, e.g.), there's no good reason to make the form resizable. If you enlarged or mazimized the form, you'd only make the area to click the button bigger, but you'd be clicking a smaller area than the button to resize it, so there's no reason. In this case, it doesn't make sense for the form to be resizable because there's no user-benefit for adding the extra control.
Now consider a form that contains a listview. There are clear usability benefits to making this form resizable in both dimensions. The listview may contain more items than can be shown in a smaller area, both horizontally and vertically, so it makes sense that this form be fully resizable to allow the user to display as much or as little of the data as they want.
Every form control implicitly has certain degrees of freedom either by constraint or by convention. Conventionally, buttons don't resize, so they have no degrees of freedom (even though they can resize). Listviews and listboxes have two degrees of freedom, horizontal to display more data per row and vertical to display more rows. Single line textboxes have one degree of freedom, horizontal. Because they're single line, they don't expand vertically, but they do expand horizontally.
These degrees of freedom help you determine the layout of your form. Form elements that have degrees of freedom should resize in the appropriate direction when the form is resized. I prefer to design my forms with only one control that has two degrees of freedom in an area where areas are typically separated via splitters. I prefer to avoid the explicit table layout panel unless there's a very specific need for it because it's easy to make a form overly complex when there's a table layout to work with. The anchors in WinForms provide an extremely powerful and flexible abstraction for control layout, however, so I strongly encourage their usage.
Aside from the layout panels (my favorite is the table layout), become familiar with the Anchor, Dock (more for the table layout), and MinimumSize properties. They do a lot of work for you when it comes to resizing forms.
Most of your forms will look goofy maximized but my general rules were these:
Buttons stay the same size
regardless of form size (no Top and
Bottom anchor; no Left and Right
anchor).
Buttons stay in the same place with
respect to a border (Anchor
combinations: {Left, Top}, {Left,
Bottom}, {Right, Top}, {Right,
Bottom})
Only the right-most textbox grows
when resizing (Anchor = Left and
Right).
Single multiline textboxes rule the form
(Anchor = Left, Right, Top, Bottom)
With multiple multiline textboxes, the lowest one rules the form.
MinimumSize is less that 640x480 whenever possible; 800x600 max.
The default size is the MinimumSize -- let the users make it bigger if they need to.