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, ...)