custom view-based nstableview resizing - objective-c

I have an NSView class, which draws it's contents on a CALayer. These NSView classes are held in an NSTableView which has a single column. I need to make it so the NSTableView adjusts it's size to fit the contents of the NSViews it contains, which can have variable widths, i.e. the NSTableView needs to have the same width as the widest cell. This in turn will allow the user to scroll if the cells' widths are larger than the available area.
Think of it like a multitrack audio editor, where each view is a track, but the tracks can have different lengths.
At the moment, the NSView cells seem to adjust width automatically to the size of the table column, so I can see two possibilities: One is to make it so the cell NSViews set their width, and somehow have this promulgate everywhere else. The other is to have the tableview or nstablecolumn set its width based on the maximum width. I have tried setting the NSTableColumn width and minWidth, but this doesn't seem to work (it doesn't always adjust to the correct size, if the size is big).
Any suggestions or help to make this work?

If you're using CALayer (lets call it root layer) to draw the view contents, try to create another CALayer which will be a child of the root layer (this would be the audio track). You can set the size of the child layer independently and also you will know which one is biggest.
Root layer will always be as big as the table view, as you said:"NSView cells seem to adjust width automatically to the size of the table column" - don't try to change root layer size, but child layer size.
Once you determine the widest child just change table view frame to be the same width.

Related

Use Page Width when printing NSTableView instead of the view width

This seems like it should be simple...
I have a basic NSTableView in a window. The window is arbitrarily resizable (width + height). The tableview is pinned to the edges of the window and it has a single column that contains view-based table rows. The table rows have content pinned to the left and right edges of the cells, so as you resize the width of the window, you are effectively adjusting how much white space is in the middle of the cell.
I'm now trying to implement printing for this tableview. When I set up the NSPrintOperation, I'm passing my tableview subclass as the view to print. My desired result is this: I want the width of the tableview to be resized to the width of the page (regardless of how wide the window is right now on screen). I don't want to adjust the scaling factor (because that affects width + height) - I simply want the result to be as if I manually resized my window to exactly match the width of a printed page and then hit "print".
I've tried setting horizontalPagination to .fitPagination - but the problem there is that seems to apply a scaling factor to the width + height (which means if the window is currently "very wide", it makes the row height really small as it compensates for the width).
I've tried overriding adjustPageWidthNew:left:right:limit: in my tableview subclass - but that never gets called.
I suppose I could create a duplicate tableview and re-set it up exactly like the one I have on screen, but that feels like overkill when the view I want is already good to go - I just need to temporarily resize the width while I'm printing.
Any ideas?

NSTextField stops resizing when not editable

I currently have a split view and when i resize the app window i want only the right subview to get larger (so left stays exactly the same size). I have a nstextfield in the right subview where i can type stuff in. However, in certain circumstances I call [_textFieldInQuestion setEditable: NO]. After doing so, when i try to resize the app, the right will get larger up till a certain point, then the left will grow. I saw a post on SO where I should subclass the nstextfield to achieve the behavior, but i was wondering if there were any alternatives that were more elegant and if not, how does one go about override the autolayout methods to produce the behavior i described.
When a text field is non-editable, it has an intrinsic width based on its content. (When it's editable, it doesn't make sense for the text field's width to track its content because its content is not "intrinsic".)
The text field's horizontal Content Hugging priority is presumably higher than the Holding priority of the left view of the split view. So, the text field resists "stretching" to be wider than its content at a higher priority than the left view resists being increased in size.
Reduce the text field's horizontal Content Hugging priority and/or increase the left view's Holding priority so that the former is greater than the latter.

Cocoa: rearrange subviews when parent view resizes

I have an NSView with a number of subviews (e.g. NSLabel). I want these subviews to be aligned in a row, but if the parent view doesn't have enough width, I want the subviews to be wrapped to the lower leftmost space - just like words in English text when the line cannot fit them all.
I thought it can be done with Auto Layout, but I can't make it work. When my simple window with two labels and simple horizontal constraints resizes, the labels just overlap each other. Instead, I need the rightmost label to "jump" to the lower leftmost position.
How can it be done? Should I keep researching the Auto Layout feature?

Resize NSTableView or NSScrollView depending on number of rows in table

I have a view-based NSTableView which is embedded in an NSScrollView. It has custom cells that are x number of pixels high. The NSScrollView is the same size as the panel that it is a subview of. I want to resize the entire NSTableView depending on how many rows are in the table.
Everything is working except the resizing. Resizing the scroll view manually in IB seems to have the desired affect, but NSSrollView does not seem to have a class method to resize its view (like NSView has setFrame). Should I be resizing the scollview, the tableview, both, or something else? Does NSScrollView have a setFrame method or similar that I am missing?
Thanks.
Before you try to do it programmatically, make sure you have the outline view's autosizing masks set up properly in the nib file. It sounds like you simply want the outline view (and its scroll view) to always remain the same size as the window that it's inside.
By default, the autosizing masks of an NSScrollView/NSOutlineView combo that you place into a window looks like the following:
In other words, it's set up to always remain the same size as it is now, no matter how large you resize the window to be.
What you want to do is to change the autosizing masks to look like in the image below:
To do that, you click in the white autosizing box wherever there's a dotted red line to toggle it into a solid red line. Once it's configured that way, the scroll view (and table view) will always (automatically) be resized to be the same size as the window that it's in.
There may also be a way to achieve this using Lion's new "auto layout" feature, but I'll have to leave that to someone who has more experience with it.
In case you really need to do this (such as when you want all rows to fit in the scrollview alleviating the need to scroll) and the scroll view is only a portion of the window/view you can do:
[[myTableView enclosingScrollView] setFrame:newFrameRect];
scrollview.frame = CGRrectMake(x, y, w, h);

Programmatically reveal a UIView

I am attempting to reveal (through animation) a UIView. Specifically I want to show the center portion of the view and then slowly reveal the outer edges of it (sort of like pulling back a curtain).
My first attempt was to simply set the bounds rect to be smaller and animate it to be the full size of the view's frame, but this did not have the desired effect since by changing the bounds I was also changing the frame.
If what I am trying to do does not sound possible (at least not in a simple manner), at least I would like to be able to have is some way to make the subviews of the main view stationary relative to the screen, NOT their parent view, as the parent resizes (this would give a similar effect).
Any ideas?
Thank you,
-Matt
It definitely is possible. What you need to do is
For the view you're animating, setAutoresizesSubviews:NO and setClipsToBounds:YES.
Set the view's bounds (NOT the frame) to a rect with zero size and origin at the center point of the rect you want the view to occupy when it is fully revealed (in the view's own coordinate system). In other words, startBounds.origin.x should equal half of endBounds.size.width and similarly for y.
Position the view by setting its center (in the parent view's coordinate system).
In an animation block, change the view's bounds to zero origin and full size.
In the animation's completion block, you probably want to setAutoresizesSubviews:YES again.
You may also need to set the view's autoresizing mask to be fully flexible (springs but no struts), depending on what other layout gets triggered as you resize.
Sounds like you want to change its clipping. A cheap (code-wise) way to do that would be to insert the view into a parent view (with autoresizing set to center it), set the parent to clip its children and then animate the parent's frame.