Skip to content

Instantly share code, notes, and snippets.

@jwilling
Last active March 5, 2023 22:01
Lets help improve AppKit.

Is AppKit causing you frustration? Instead of just complaining about it, lets try to make it better by compiling a list of specific problems with AppKit. Leave a comment below, and I'll include it in the list.


##NSView##

  • NSView does not have the ability to set an affine transform (rdar://15608609)
  • Controls that have cells (such as NSTextField) do not respond properly when layer-backed. Take NSButton as an example. When not layer-backed, it will animate properly using the animator proxy. When layer-backed, using the animator proxy breaks focus rings (they jump to destination immediately). Currently, directly manipulating the layer of a cell-based control is not supported (and will lead to a broken interface), but is much needed. (rdar://15608822)

##NSViewController##

  • NSViewController could be more useful. It has -loadView but no other lifecycle methods. (rdar://15608948)

##NSClipView##

  • NSClipView has performance issues. Improved under 10.9.
  • NSClipView has a poor animation when using -scrollRectToVisible:. (rdar://15609175)

##NSTableView##

  • NSTableView has odd animation artifacts when scrolling with the keyboard with a fast key repeat.
    • Due to the clip view issue mentioned above. (rdar://15609175)
  • NSTableView does not fully support sections – all rows in the table are numbered sequentially, rather than as (section #, row #) as UITableView does. This makes it difficult to alter sections independently. (rdar://15609306)

##NSCollectionView##

  • NSCollectionView is not performant. It loads every single cell all at once, and it keeps them all in memory. It does not reuse cells. (rdar://15609666)

##NSBrowser##

  • NSBrowser is not view-based like NSTableView and NSOutlineView.

##NSSlider##

  • NSSlider requires use of private method -_usesCustomTrackImage in order to completely customize appearance.
  • NSSlider needs a "rounded textured" style for use in window frames (like in Finder).

##NSSearchField##

  • NSSearchField does not support tokens.

##NSTextField##

  • NSTextField does not support a custom context menu when the text is selectable and/or editable. It requires hacking around with the field editor to implement this functionality.

##NSSplitView##

  • NSSplitView makes simple customization like setting priorities and min/max sizes for views is unnecessarily complex.

##NSProgressIndicator##

  • NSProgressIndicator still draws the original progress bar even if drawing is overridden. (rdar://15609817)
  • NSProgressIndicator's color cannot be changed without workarounds such as Core Image filters. (rdar://15609817)

##NSPopover##

  • NSPopover does not offer a way to customize its appearance apart from the two default styles.
  • NSPopover steals keyboard focus.

##NSWindow##

  • NSWindow animation is poor without the use of some not-so-nice hacks.
  • Borderless NSWindows (NSBorderlessWindowMask) do not have the ability to round their corners.
  • Borderless NSWindows with a layer-backed content view do not get a shadow.
  • NSWindow is really difficult to customize.

##NSDocument##

  • NSDocument has very bad support for documents that aren't fully loaded into memory. Nearly all of the API assumes that you can generate a singular NSData object to store your document in, which isn't true if half of your document is on disk only and the other half in memory only.
  • NSPersistentDocument doesn't support file wrappers (bundles), even though that's a requirement for the sqlite data storage with sandboxing enabled. All workarounds at this point are huge hacks.

##NSObjectController##

  • While NSObjectController and its subclasses (e.g. NSArrayController) support retrieving objects from a Core Data managed object context, they do not offer a way to receive per-change notifications. This means that you need to reload your entire view vs. inserting/removing/moving the cells that were updated. Ideally, we would want a port of NSFetchedResultsController.

##NSDrawer##

  • NSDrawer should either be deprecated or have its API fully updated to support customization.

##NSImage##

  • NSImage does not support drawing stretchable images with caps.

##Field Editors##

  • Field editors are conceptually unusual and confusing.

##Cells & Controls##

  • The use of cells in specific controls such as NSTextField and NSButton make them difficult to customize.
  • NSButtonCell is poorly thought out. bezelStyle, gradientType, buttonType, isHighlighted, state and a few more make for a really really confusing subclassing experience.
  • NSTextFieldCell does not have vertically-centered text. A subclass is required.
  • Template images and window-style engraved text should be useable without the use of captive cells.
  • AppKit controls need image-based customization properties like their UIKit counterparts.
  • AppKit does not provide HUD-styled controls.
  • Interface Builder does not support bindings for custom controls.

##Misc. (not necessarily AppKit)###

  • There is no Cocoa wrapper for the Carbon hotkeys API.
  • There is no Cocoa wrapper for FSEvents. The Spotlight stuff doesn't really work for sandboxed Applications.
  • There is no API for AirPlay.
@jwilling
Copy link
Author

jwilling commented Dec 6, 2013

@corbinstreehouse Sorry, I never received a notification for your comment. I'm not sure how many of these are filed as radars, but when I get a chance I'll run through again on 10.9 and file any of the ones that remain as unfixed and update with the radar numbers.

@CodaFi
Copy link

CodaFi commented Apr 20, 2014

  • Things that still cannot have weak references despite (ideally) having trivial backing variables:
Class Ideal Backing Reason Radar
NSATSTypesetter CTTypesetterRef Instances are cached internally -
NSColorSpace CGColorSpaceRef Instances are basically immortal rdar://16669956
NSFont CTFontRef Manually controls its own retain count rdar://16669960
NSParagraphStyle CTParagraphStyleRef Manually controls its own retain count (is actually one of its flags) rdar://16669966
NSMutableParagraphStyle (See Above) (See Above) rdar://16669966
NSTextView None Goes to great pains to manually manage its own retain count -
  • NSParagraphStyle should not have a mutable subclass. It should have immutable mutator methods that generate copies (rdar://16669988).
  • NSPasteboard does not send notifications for changes, nor does it have any means of observing changes in what is posted from any end of the pipe (rdar://16669974).
  • CFPasteboard has been around a long time, yet still hasn't been made public (rdar://16602986).
  • Layer-hosting DockTile and Status Bar custom views do not draw (rdar://16534607).
  • The command panel for NSSpeech[Recognizer/Synthesizer] is not public, and still hidden in Carbon (rdar://16670002).
  • There's still no UIDevice-like class despite there being a well-maintained Machine Attributes plist backing the About This Mac panel (rdar://16670004).
  • NSSound uses either the deprecated parts of AudioToolbox, or the deprecated parts of CoreAudio. Either way, it's pretty crufty up in there. Needs some OpenAL love (rdar://16670028)
  • So much of CGL is deprecated, it's basically useless.
  • NSCursor does not expose diagonal cursors (rdar://16695476), however they are a part of the JDK.
  • NSScreen does not bow to object equality (rdar://16737571)
  • NSRunningApplications hash to 0, meaning they really don't like being put in NSSets.
  • NSPrintInfo exposes an NSMutableDictionary.

@konstantinpavlikhin
Copy link

Ideally, we would want a port of NSFetchedResultsController

Have a look at KSPFetchedResultsController.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment