Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently subclassing standard Cocoa controls

Tags:

cocoa

controls

In spite of there being a Human Interface Guidelines document (HIG), a lot of high quality Mac desktop applications use custom controls. My question is what is the best approach to start subclassing controls for Cocoa development? It surprises me how little (good) information there is on this topic. What path is the best to follow so you don't end up with a nice but half broken control?

like image 271
Bart Jacobs Avatar asked Feb 05 '11 13:02

Bart Jacobs


1 Answers

Here's a checklist:

  • Make sure your control works correctly at double resolution. Use Quartz Debug to test this. You'll want to test both drawing sanity (in all states—normal, selected, pressed, disabled, and any others) and operation sanity (that hit testing matches where things appear on the screen/other destination device).
  • For extra credit, make sure your control works correctly at 1.5 (or some other, similarly non-integral) resolution.
  • Test how the standard control works when clicked. You'll probably do this anyway. Do as the standard control does.
  • Test how the standard control works when half-clicked (mouse down inside, mouse up outside).
  • Test how the standard control works when dark-side-of-the-clicked (mouse down outside, mouse up inside).
  • Test how the standard control works when dragged within.
  • Test above four with the other mouse buttons (right and middle).
  • Test what the standard control does when you scroll with a scroll wheel. Also test shift + scroll and, on a mouse that has them (e.g., most Logitech mice), scroll left/right buttons.
  • Test what the standard control does when you two-finger scroll in each axis and in both axes.
  • Test what the standard control does when you pinch and when you unpinch.
  • Test what the standard control does when you swipe with three and four fingers in each axis.
  • Test how the standard control works with “Full Keyboard Access” turned on. Can you tab into it? Can you press it with the space bar? Can you enter it with the return key? Can you tab out of it?
  • Test how the standard control responds to Accessibility queries. Use Accessibility Inspector. See the Accessibility Programming Guidelines for Cocoa for information on responding to accessibility queries and messages in your control.
  • Test your app—including, but not limited to, your custom controls—in VoiceOver. Blindfold yourself and try to use the app with VoiceOver alone.
  • If applicable, test printing your view. You can print to Preview if you don't want to kill a tree for your development process.
  • Test printing in other paper sizes. If you're in the US, test A4; otherwise, test US Letter. Test still other paper sizes (such as Legal and A3) if you're feeling thorough.
  • If you're implementing a scroller (poor you), test that your scroller responds correctly to the “Jump to the (next page|spot that's clicked)” preference in the Appearance pane in System Preferences. “Correctly” means it should do what the user selected.
  • Make sure it correctly implements all four scroll-arrow-position settings: One at each end (Mac style), both at the lower/left end (NeXT style), both at the upper/right end, and both at each end (power user style). As always, you need to both draw correctly and hit-test/react correctly. (Suggested by @radiofreelunch/by David Dunham)
  • Also, if you're implementing a scroller, make sure it responds to the “Smooth scrolling” preference correctly.
  • Test that it responds to different scrolling speed preferences correctly.
  • If you're implementing a text entry field of some sort, or any view that responds to some sort of special hot key (like Enter to send a message in an inputline), test right-to-left (Hebrew/Arabic) text input and alternate input methods. The Character Viewer is a good start.
  • Also, test that you don't break ctrl-q. For example, ctrl-q, tab should always enter a tab character. The same typically goes for option + (key), such as option-return in an inputline.
  • Test that it responds to different key-repeat preferences correctly.
  • If you implement any custom keyboard shortcuts (⌘ + zero or more other modifiers + one or more character keys) by means other than Cocoa's standard menu shortcut handling, test your custom shortcut behavior under Dvorak. There is no faster way to sour our perceptions of your app than to respond to ⌘' by quitting.
  • Show your app to users who've never used it nor seen any mockups before. Disqualify programmers. If they don't recognize your control as a (whatever it's supposed to be), redesign it. If you ever say “the scroller is over here” or “you need to click that”, you instantly fail.
  • Test that your control responds (or doesn't respond, if responding would be dangerous) when your app is in the background. (Suggested by @chucker.)
  • Test that your control responds, but does not bring the app forward, when your app is in the background and the user clicks on it with the ⌘ key down. (Suggested by @chucker.)
  • Test resizing your view. Among other things, this will ensure that you set the autoresize mask correctly. You're also looking for drawing bugs—distorted elements, gaps, etc. (Part of this suggested by @Bagelturf.)
  • If your control is, in fact, a control, send it sizeToFit and make sure that it does the right thing. (Suggested by @Bagelturf.)
  • If you work with mouse coordinates, don't assume that they will be whole numbers. Ensure that you handle fractional numbers, zeroes (positive and negative), and negative numbers correctly. (Part of this suggested by @Bagelturf.)
  • You might also consider splitting your control into a control and a cell. In the latter case, also perform all of these tests on your cell embedded in an NSMatrix and in an NSTableColumn.
  • If your control has a menu, test what happens when the control is at one or more edges of the screen. The menu should move over to not fall outside screen space.
  • If your control has a menu, test that the user can enter it with the down arrow key when using “Full Keyboard Access”. If it is also a text field (like a combo box), test that this only happens when the user presses the down arrow at the end of the text; otherwise, normal text field behavior should rule: Pressing down on a line that is not the last line should move the cursor down a line, and pressing down on the last line should move to the end of the line.
  • If your control has a menu, test that it stays open when clicked and does not immediately close when held open. There is a function you can use to do this correctly, and it is available in 64-bit.
  • If your control has a menu, test that it is navigable (all four arrow keys + Home, End, Page Up, Page Down), usable (spacebar/return press action), and cancellable (esc) with the keyboard.
like image 118
Peter Hosey Avatar answered Sep 21 '22 07:09

Peter Hosey