Is there any Cocoa control equivalent to WPF's itemscontrol? I have been using a single column, view based NSTableView but can't seem to get individual rows to size to fit their content, or even to get different height rows (all views are sized to be as tall as the tallest one).
More generally speaking, is there any way of getting views to size to fit their content? I have been using constraints, but seem to only be able to make views size according to their container's size.
You should use NSTableViewDelegate and it's -tableView:heightOfRow: method to specify the individual row height.
Related
I have a number of UI elements like panels, edit fields, buttons, labels etc. so panels contain other panels which contain input fields, editors and so on. Most of the elements are editable and/or resizable which means whenever I change anything, a lot of adjacent UI elements should change their width, height and x/y position on the pane. It works fine with a small number of elements but incredibly slow when the number of elements is thousands.
Is there a fast layout algorithm which can be used in this case? Note that I cannot use any existing layout managers and should come up with my own implementation.
I'd suggest taking a leaf out of the Android playbook and have a larger 'grid' and keep everything sized in modular multiples - this avoids you needing to solve the knapsack problem everytime!
For example, instead of having a button with an width of 80 and a height of 40 you store this as metadata as {2:1} (assuming your layout grid is 40^40 squares).
This way if you have a work panel with space of, say, {2:12} this could be filled with two objects of size {2:6} or maybe 3 of size {2:4}.
It's pretty simple to fit-to-max too as any available space can just be scaled up (say you delete a {1:1} item you can just expand the one next to it to take the space etc - you can of course create your own rules around whether objects can scale in single directions etc.
The other advantage of this approach is that you can easily manage different screen sizes and resolutions too while still keeping the same framework and look and feel.
Since Jason Smith didn't recommend Relative layout and said that we should use Absolute layout I have a question how can we deal with RelativeToView concept?
Absolute Layout sets proportional coordinates and sizes of the elements within itself relative to itself not to each other as RelativeLayout. What to do if I need some elements to be relative to each other? Creating additional Grids and StackLayouts? I would rather use RelativeLayout then or I am missing something.
Decided to add a simplest example and consider we are talking ONLY about Relative and Absolute layouts, no Stack, no Grid. I have 2 buttons and I want to place them as shown in the picture
With absolute layout I could define the position of the top button and say it's height 10% of the screen. Now I could shift the bottom button by saying it starts at 11% of the screen. BUT this will change my top button height. If I want my top button to be it's natural "auto" size I cannot do that. So, how can I put my bottom button under top one if I have no idea how much top button occupies on screen? I know how to do it with Relative but how I can do it with Absolute Layout?
It looks like the solution is nest bunch of layouts https://developer.xamarin.com/guides/xamarin-forms/user-interface/layouts/absolute-layout/
Is that the only way? Is that performance still better than Relative layout?
By its nature RelativeLayout is powerful and offers layouting options that no other Layout on its own does. But that power comes at a cost in performance. Resolving the constraint dependencies consistently and obtaining a final layout doesn't come cheaply.
The point is not necessarily that RelativeLayout should never be used, rather that often times other Layouts can do the job, and yes, even 2-3 nested Layouts can be more performant than a single equivalent RelativePanel.
Grid in particular is a powerful option with which similar effects can be achieved by astute use of Auto, Star, and/or absolute-sized rows and columns as appropriate, plus RowSpan and ColumnSpan, plus element margins, etc.
To consider your specific example, I don't know of a way to achieve what you want with an AbsoluteLayout, at least without the added complication of attached properties. But it seems like a natural fit for a Grid with RowSpan="Auto" on the first row. From a diagram alone I can't tell exactly what other constraints you're going for.
I have nine images ad I want them to display in a single column on the device. The images should retain their original height and width (that I will set) and the only thing that should change according to the screen height should be the distance between the images.
I'm not really sure how to approach this problem - I tried using a container, but it didn't turn out as I expected. Should I set the constraints programmatically? And if so, how? What should the constraints be if I want the images to be from top to bottom of he screen?
Consider using a stack view:
On iOS, UIStackView provides UIStackViewDistributionEqualSpacing, which I believe will arrange images as you want
On Mac, NSStackView can automatically space images as you describe if the individual image views are all in the same gravity and retain their sizes at a high enough priority (using constraints or content hugging priority)
I'm starting with JavaFX on a new application and I want to get a layout on screen identical to WPF's UniformGrid. There's TilePane but it's different (similar to WrapPanel I guess).
My approach so far would be (for a collection [size = N] I want to display as "tiles"):
Use a TilePane t.
t.setPrefRows( ROUNDUP( sqrt(N)))
That's probably not the best approach.
Do you know a better solution? Maybe a resizable one?
It sounds like you want a layout which:
Has a fixed number of cell nodes in each row.
Each cell node has the same height and width.
I'm not familiar with WPF or UniformGrid, but I think the above is what you want.
TilePane likely isn't a Good Fit
It seems like TilePane would be a good fit for this, but, as you found out, it doesn't really exhibit this behaviour out of the box. With a TilePane, you set a preferred number of rows, but as you resize the TilePane the number of rows and the number of columns can change as the tiles are rearranged to fit the available area.
Use a GridPane with Binding and Preference Settings or Constraints
To get a fixed number of cells per row, use a GridPane. A GridPane will keep a fixed number of rows and columns as it resizes. To ensure that each cell node has the same height and width, you can listen to the height and width properties of the GridPane and, on change, set the min/max/preferred sizes of the child elements so that they all have the same size. Or set some constraints on the GridPane rows and columns such as setPercentWidth and setPercentHeight.
To demonstrate this approach, the ColorChooser sample provides some code for a re-sizable ColorChooser with a fixed number of color swatches per grid row and as the overall containing grid grows or shrinks, the color swatches are grown and shrunk to fit the available area as appropriate. The color swatches themselves don't necessarily maintain the same height/width ratio, but you could easily achieve that by setting appropriate min/max/preferred sizes on the child elements.
Create Your Own Layout
As an alternative to using change listeners and setting min/max/preferred sizes on children, you could implement your own layout manager by subclassing Pane to create a UniformGrid class and implementing the layoutChildren method. In layoutChildren, arrange the size and position of UniformGrid children as needed. You can refer to the source code of an existing Pane to find an example of how to create your own layouts.
Investigate 3rd party Layouts
The ControlsFX project has a GridView or MigLayout which might provide the functionality of a UniformGrid.
I want to load a table view with cells. In between cells I should able to see minimum cell gap. How can I increase existing table view cell distance in my navigation controller root view?
You can't increase cell distance, but what you can do is subclass UITableViewCell, override -layoutSubviews, and reposition all the internal views to allow for a bit of padding on one (or both) end(s) of the cell.
That said, I can't think of a single app on the iPhone that has a cell padding like this. You should think very carefully before doing this, as it's quite non-standard.
+1 you cant increase cell distance. However you can make it look that way: custom cells are easy to make in IB, and good custom cells are worth their weight in gold. You could set the cell spacer to none and a desired hight while making two UIImageViews (or a label with a cheeky string of underscores) in the cell to create the illusion of a cell boundary.
Here is a good tutorial on custom cells (I recommend watching the screen-cast):
http://icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/