Wednesday, July 18, 2012

Segue (not segway)

Segue's in iOS are a way to move from one MVC to another.  Segues are in storyboards and storyboards are only available in iOS5.
  • push - in a UINavigationController
  • replace - replaces right-hand side of UISplitViewController (iPad only)
  • popover - puts view controller on screen in a popover (iPad only)
  • modal - puts view controller up in a  way that blocks the app until it is dismissed
  • custom - create your own subclasses of UIStoryboardSegue

[self performSegueWithIdentifier:@"MySegueIdentifierHere" sender:self];

Before the new storyboard

- (void) prepareForSegue:(UIStoryboardSegue *)segue
{
  if ([segue.identifier isEqualToString:@"MySegueIdentifierHere"]) {
    UIViewController *newController = segue.destinationViewController;
    // send messages to the newController to get it ready for screen
    // but, the segue actually does the work of putting the new controller on screen
  }
}



Controllers of Controllers in iOS

In iOS there are some constructs built into the system to enable controlling a bunch of controllers.

UINavigationController

  • Has property 'rootViewController' that points to another MVC.  The rootViewController controls which view is displayed in the "Custom content" area.
  • Performing a segue to push a new MVC's view onto screen, other one slides off the screen.  When the segue is completed the new view has a back button in the Navigation Bar at top.  When click the back button you pop the current view off the navigation stack and, generally, remove it from the heap.  Those earlier views/mvc's remain in the heap.
  • segues always create a new view controller

Am I wider or taller?

Within a UIView (or subclass) you have access to a 'bounds' property.  You can use this to determine whether or not you are wider or taller:

- (NSString *) amIWiderOrTaller {
  if (self.bounds.size.width==self.bounds.size.height) {
    return @"Same";
  } else if (self.bounds.size.width > self.bounds.size.height) {
    return @"Wider";
  } else {
    return @"Taller";
  }
}

- (CGPoint) getMidpoint
{
  CGPoint midPoint;
  midPoint.x = self.bounds.origin.x + self.bounds.size.width/2;
  midPoint.y = self.bounds.origin.y + self.bounds.size.height/2;
  return midPoint;
}

Tuesday, July 17, 2012

Sunday, July 8, 2012

Xcode Debugger

Apple Xcode debugger documentation
Also, Paul Hegarty's Debugger Video on iTunes.

The debug console (lower right) has a prompt (e.g. (gdb) or (lldb)) where you can enter commands to get some feedback about objects at the current breakpoint.

(lldb) print self

(lldb) po [self someObjectGetter]


You can also do conditional breakpoints.  Conditional breakpoints mean that at some point in your program you only want a breakpoint to interrupt your program when a certain 'condition' exists.  For example, if you have an int value variable and you only want it to break when the value == 3.

To make a breakpoint conditional in Xcode, right-click on the breakpoint and select 'Edit Breakpoint' from the popup menu.  A little popup dialog (see image) will be presented.  Enter the desired condition and click done.

Saturday, July 7, 2012

Xcode crash dialog


How do you traverse an NSArray?


From HERE

NSEnumerator *e = [array objectEnumerator];
id object;
while (object = [e nextObject]) {
  // do something with object
}

Friday, July 6, 2012

Another implementation plan


Screen: Performance Dashboard


Screen: Share your Accomplishments


GHUnit

If you are using Xcode 4.3.3 (or greater), when you modify your Tests/Supporting Files/main.m you will need to perform  slightly different:
  • Add #import <GHUnitIOS/GHUnitIOSAppDelegate.h>
  • Add 

return UIApplicationMain(argc, argv, nil, NSStringFromClass([GHUnitIOSAppDelegate class]));


So you end up with at least two targets.  One target for the main project (MyTestableApp) and one target for the testing area (Tests).  In order to test classes from the main project you will need to add them to the "Compile Sources" section of the Tests target's Build Phases:



GHAssertNoErr(a1, description, ...)
GHAssertErr(a1, a2, description, ...)
GHAssertNotNULL(a1, description, ...)
GHAssertNULL(a1, description, ...)
GHAssertNotEquals(a1, a2, description, ...)
GHAssertNotEqualObjects(a1, a2, desc, ...)
GHAssertOperation(a1, a2, op, description, ...)
GHAssertGreaterThan(a1, a2, description, ...)
GHAssertGreaterThanOrEqual(a1, a2, description, ...)
GHAssertLessThan(a1, a2, description, ...)
GHAssertLessThanOrEqual(a1, a2, description, ...)
GHAssertEqualStrings(a1, a2, description, ...)
GHAssertNotEqualStrings(a1, a2, description, ...)
GHAssertEqualCStrings(a1, a2, description, ...)
GHAssertNotEqualCStrings(a1, a2, description, ...)
GHAssertEqualObjects(a1, a2, description, ...)
GHAssertEquals(a1, a2, description, ...)
GHAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
GHAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...)
GHFail(description, ...)
GHAssertNil(a1, description, ...)
GHAssertNotNil(a1, description, ...)
GHAssertTrue(expr, description, ...)
GHAssertTrueNoThrow(expr, description, ...)
GHAssertFalse(expr, description, ...)
GHAssertFalseNoThrow(expr, description, ...)
GHAssertThrows(expr, description, ...)
GHAssertThrowsSpecific(expr, specificException, description, ...)
GHAssertThrowsSpecificNamed(expr, specificException, aName, description, ...)
GHAssertNoThrow(expr, description, ...)
GHAssertNoThrowSpecific(expr, specificException, description, ...)
GHAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...)



Monday, June 4, 2012

Storyboarding

Storyboarding is about tasks.
It's not about pretty pictures, but rather about communicating ideas.  Visually communicating ideas.
Storyboarding should illustrate a goal.

Storyboarding Objectives:
Setting

  • Actors/People involved
  • Environment
  • Task being accomplished

Sequence

  • What steps are involved?
  • What leads someone to use the app?
  • What task is being illustrated?

Satisfaction

  • What motivates people to use this system? (cost, efficiency, ease of use)
  • What does it enable people to accomplish?
  • What need does the system fill?  (distribution of information)

Storyboards help people get on the same page.
Make the time to make a storyboard short. (e.g. 10 minutes max)


-- Scott Klemmer

Sunday, May 27, 2012

UI

Guts from HERE.


  • The underlying data structures should not define the UI. UI should not define underlying data structures.
  • Good UI can use a transform to convert data structure into appropriate UI data. 
  • Make the next step obvious. 
  • Need must proceed Technology. 
  • Postpone platform choice until you know what you need to build. Start with real use cases. Think in flows, not in features. 
  • People must experience the UI in order to form an opinion about it. (Cannot just look at screenshots) 
  • Prototype often (and abandon prototypes often). Schedule prototypes for delivery in a sprint. It's an evaluation tool. Build them fast. Build quickly, checkout quickly and dispose of prototypes without regrets. 
  • Make prototypes simple (so they don't take long to do) and can be evaluated quickly. 
  • Simplify. Reduce the number of perceived things. Reduce visual clutter. (Cognitive load increases with each element on the screen.)
  • User interface perception:
    • negative shape and aesthetics (Emotional) - user identifies what is unpleasing and pleasing. user already has an idea if they will like it or not before they even use it.
    • element parsing and counting (workload) 
    • use first element first (execute)
  • Keep error messages in context. (see how the error messages are in close proximity to the field of entry)

  • In touch interfaces, denote scrollable areas by clipping content.
  • Leverage muscle memory and be consistent. (consistent layout even within sections)
  • Think outside the page load.  If you can do stuff in-place then do it. (minimize context shifts) Pagination by detecting scroll movement.
  • Use transitions to change states.
  • Iterate and refine.
  • Find out what users like and dislike. (Have surveys, talk to users, build into application)
  • Never break the user experience. 
  • Provide customer with a great experience. (Don't shut get the darned product shipped.)

Engineering UI: (ugly, blocks you from having a positive emotional item, lots of workload-may seem like a lot, ton of work for user, causes page abandonment)
Redesign of same page: same fields, broken into multiple steps, element parsing and counting (workload) is much lighter than previous.  Notice how the field labels are light grey inside the field instead of a separate label.
Sunroof control screen in Tesla Model S (17" Touch Screen)
...can also drag on the sunroof on the screen:





Wednesday, May 16, 2012

Monday, May 7, 2012

Enabling File Sharing in iPhone/iPad application


To enable File Sharing in an iPhone/iPad application, you set the boolean flag “UIFileSharingEnabled” in the application's info.plist.


User friendly key:
Raw friendly key:



View Controller Catalog