Skip to content

Latest commit

 

History

History
 
 

DateDiff

{\rtf1\ansi\ansicpg1252\cocoartf909
\readonlydoc1{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fmodern\fcharset0 Courier;}
{\colortbl;\red255\green255\blue255;}
\vieww9000\viewh8400\viewkind0
\deftab720
\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\pardeftab720\ql\qnatural

\f0\b\fs44 \cf0 DateDiff
\b0\fs22 \
\
DateDiff is a small application which demonstrates simple uses of NSDatePicker, NSCalendar, NSDateComponents, and NSValueTransformer classes.  The UI is put together with bindings and target/action methods.\
\
DateDiff has two classes: DateDiffCalculator and MaxIntegerToZeroValueTransformer.\
\

\b DateDiffCalculator
\b0  holds:\
\pard\tx160\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\pardeftab720\li180\fi-180\ql\qnatural
\cf0 -	Two dates 
\f1\fs24 date1
\f0\fs22  and 
\f1\fs24 date2
\f0\fs22 , as instances of NSDate\
-	Their difference, 
\f1\fs24 diff
\f0\fs22 , instance of NSDateComponents\
-	Five booleans (
\f1\fs24 doesYear
\f0\fs22 , 
\f1\fs24 doesMonth
\f0\fs22 , etc) to determine what calendrical units the difference should contain\
\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\pardeftab720\ql\qnatural
\cf0 \
All the properties in DateDiff are implement via the ObjC2 @property feature, thus requiring no code.  These properties are connected to the UI via bindings, which also eliminates all code.\
\
The difference computation is performed expicitly by calling 
\f1\fs24 computeDateDiff
\f0\fs22 .  All UI elements in the app which change the dates are hooked up to an action method, 
\f1\fs24 computeDateDiff:
\f0\fs22 , which calls 
\f1\fs24 computeDateDiff
\f0\fs22 .\
\
Another way to do the update would have been to use observing.  There are multiple approaches here, but the most straightforward is for the class to observe in itself 
\f1\fs24 date1
\f0\fs22  and 
\f1\fs24 date2
\f0\fs22 , as well as all of the 
\f1\fs24 doYear
\f0\fs22 , 
\f1\fs24 doMonth
\f0\fs22 , etc, and update 
\f1\fs24 diff
\f0\fs22  on any change to any of these properties.  This would have required per-property code to set up observing/unobserving, instead of one target/action connection in IB per property. We opted for the IB connections rather than code, however the observation approach is more "pure" (from an MVC point of view), more general, and could work better in a more complex setup.\
\
If you wished to implement the updates via observing, in 
\f1\fs24 init
\f0\fs22 , call 
\f1\fs24 addObserver:forKeyPath:options:context:
\f0\fs22  for each property. Pass a unique context, for instance 
\f1\fs24 [DateDiffCalculator class]
\f0\fs22 .  To get informed of changes, implement 
\f1\fs24 observeValueForKeyPath:ofObject:change:context:
\f0\fs22 . Here if the context is same as what you passed, simply update the diff by calling 
\f1\fs24 computeDateDiff
\f0\fs22 ; otherwise call super.  Finally remember to call 
\f1\fs24 removeObserver:forKeyPath:
\f0\fs22  for each property, in the dealloc method.\
\
The other class in the application is 
\b MaxIntegerToZeroValueTransformer
\b0 . \
\
NSDateComponents sets undesired components to NSIntegerMax. Since we don't want to display this value in the UI, we have this  value transformer which converts the value NSIntegerMax to the empty string.  It's a very simple, one-way transformer.  Literally one line of code.\
\
Note that we don't bother registering this transformer. That's because in Leopard, an instance of the value transformer will be registered automatically if the name supplied in IB isn't found in the registry but corresponds to an existing class. Of course you can use this feature only for apps which are meant for 10.5 or newer. \
}