NSTextField’s attributedString and truncating

I have a NSTextField in a table cell view. Since it can be to long to show, I set the line break as Truncate Middle in interface builder. But no matter how I tried, the truncating just did not work.

After some investigation, I found the problem is that I set the ‘’’attributed string’’’ explicitly and it overrides the line break setting by interface builder. I have to set it when I made up the attributed string.

let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = .ByTruncatingMiddle

let attributes = [NSParagraphStyleAttributeName:paragraph]

attributedString.addAttributes(attributes, range:  range )

It is pretty obvious when you know the problem. Of course the setting of line break in interface building is overridden by the attributedString. It’s just the same as the the setting of text color, background color and so on. The line break setting is under Control section. I think that’s why I was confused in the first place.

Layout NSCollectionView with your own NSCollectionViewLayout

First, subclass NSCollectionViewLayout:

class LYExpandableLayout: NSCollectionViewLayout {
}

Tell your collection view to use the layout:

self.collectionView.collectionViewLayout = LYExpandableLayout()

No, it’s not done yet. There are several methods you need to implement in your layout class.

Override collectionViewContentSize and return the calculated content size of the collection view according to the collection items in it.

override var collectionViewContentSize: NSSize {
	
}

Tell if you want to invalidate layout when the bounds change. In most time, just return true here.

override func shouldInvalidateLayoutForBoundsChange(newBounds: NSRect) -> Bool {
    return true
}

Return a selected array of NSCollectionViewLayoutAttributes of item views according to the rect. Ideally, we figure out which item views are in the rect and only return the necessary NSCollectionViewLayoutAttributes of these item views. You can of course return the NSCollectionViewLayoutAttributes of all your item views if the performance won’t be hurt badly by this way.

override func layoutAttributesForElementsInRect(rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
    
}

Here’s the place to calculate the layout attributes. There are several attributes. If you want to control the position, frame should be the one to set. If the items overlaps, you may want to set the zIndex as well.

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> NSCollectionViewLayoutAttributes? {
    
}

Here’s an example of a customized NSCollectionViewLayout. It layouts a group of fixed sized item views with spacings. When an item is clicked, the following rows of items move downward to make a space. You can fill the space with a view to show detailed information of the item just like the album view in iTunes. download the example project

NSWindow title bar and toolbar showcase

I built a showcase for several combinations of styles of title bar and toolbar of NSWindow. Just to serve as a note of everything I want to remember about the NSWindow styles.

Title visibility

By default, the title of window is visible. window with title visible

window.titleVisibility = .Visible

This is a window with a toolbar while the title set to invisible: window with title invisible

window.titleVisibility = .Hidden

Example applications: Calendar, Notes, Xcode

Full size content view

When setting the NSFullSizeContentViewWindowMask, the content view extends to the whole window. The title bar and toolbar use a blur effect if visible.

window.styleMask |= NSFullSizeContentViewWindowMask

When both title and toolbar are visible: full size content view

When title is invisible: full size content view without title Example applications: Safari, Photos, Wunderlist

Transparent title bar

If you want to hide the title bar but still need the window buttons (such as close button, minimize button and screen button), you can set the titlebar to transparent:

window.titlebarAppearsTransparent = true

You may want to hide the title and use full size content view to get the following style.

window.titlebarAppearsTransparent = true
window.titleVisibility = .Hidden
window.styleMask |= NSFullSizeContentViewWindowMask

transparent titlebar Example application: Reeder,

Title accessory view

According to the documentation, title accessory view is a custom view you can put along with the title bar.

There are three layout choices.

At the bottom of title bar: title accessory view at the bottom of the title bar It’s at the bottom of title bar or toolbar. You can set the height of the view.

On the left of the title bar: title accessory view on the left of the title bar You can set the width of the view. The height of the title bar is fixed. If you set the height of the title accessory view, it doesn’t affect the height of the title and is clipped by the title bar. If the toolbar exist, it overlaps with the toolbar.

On the right of the title bar: title accessory view on the right of the title bar You can set the width of the view. The height of the title bar is fixed. If you set the height of the title accessory view, it doesn’t affect the height of the title and is clipped by the title bar. If the toolbar exist, it overlaps with the toolbar.

Example application: IA Writer

One thing to remember. You have to set the layout attribute before add the accessory view to the title.

Unified title and toolbar

Looks like this has been deprecated. No matter what you set, the title bar and toolbar are always unified since Yosemite.

I put the code as a project at github. Hope it helps.