Skip to content

Instantly share code, notes, and snippets.

@jwilling
Last active March 5, 2023 22:01
Show Gist options
  • Save jwilling/4186817 to your computer and use it in GitHub Desktop.
Save jwilling/4186817 to your computer and use it in GitHub Desktop.
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.
@dannygreg
Copy link

There is no Cocoa wrapper for the Carbon hotkeys API.

I fixed this in DGGHotKey.

@jwilling
Copy link
Author

jwilling commented Dec 4, 2012

@dannygreg Thanks, I'll add that.

@indragiek
Copy link

If the Core Data issue has been resolved in 10.8, then I don't think there's anything to complain about. This is for changes to make to AppKit going forward (and speaking of which, Core Data is a separate framework altogether). Regarding NSAnimation, this was a class that was used pre-Core Animation, and Core Animation has more than replaced the functionality of NSAnimation. There's nothing to do to NSAnimation except perhaps deprecate it.

@indragiek
Copy link

(last comment was in reply to @CodaFi).

@avaidyam
Copy link

avaidyam commented Dec 6, 2012

SCEvents is a good Cocoa wrapper for FSEvents.

@jwilling
Copy link
Author

jwilling commented Dec 6, 2012

Almost forgot:

  • NSView does not have a way to set the background color without subclassing or setting the layer's background color.

@jwilling
Copy link
Author

jwilling commented Dec 6, 2012

  • NSBezierPath cannot provide a Core Graphics representation of the path (CGPath), nor can it be initialized with one.

@jspahrsummers
Copy link

NSAnimation should be deprecated immediately in favor of Core Animation.

@CodaFi @indragiek This isn't tenable with current APIs, since NSAnimations are the only way to animate windows right now.

@uchuugaka
Copy link

also NSAnimation is the only way to animate controls that do not provide access to their components, like NSSlider's knob.

@corbinstreehouse
Copy link

Hi all,
For this to be really useful you should relate the Apple provided "radar numbers" for each issue, so it is officially logged with Apple and the appropriate AppKit engineers are aware of the issue.

@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