Photo

Started working on replacing the paper directories in the Karma Bird House with digital displays. 3x 39" Panasonic LED HDTVs are currently each loading static images from a USB drive. They will soon be replaced with Beaglebone Blacks loading web pages - allowing all three displays to be updated remotely all at once (and some other fun features). Also working on a nice stainless steel bezel to make the whole package a bit nicer looking.
1 note
·
View note
Text
Hello Again!
Hello again, internet! It's been a while since we've talked, and I think it's about time to change that.
Over the past few months, I have finally completed my Master's degree, and am back at working full time without distractions.
Craig Winslow and I are fresh off completing a storefront installation for Bucketfeet shoes at their popup store at 108 Wooster St in NYC. There is a live stream of the installation here, and it will be up until August 1st. Check it out if you are in the area at night, and we will be posting an official video of the project soon.
Right now, I am catching up on all of the WWDC videos that I can watch, and plan to dive into Swift by updating Country Perfume to use as many of the new toys that I can fit, while adding 10 new farms to the database.
We are also getting ready to film a Kickstarter video soon, I will reveal all of the details as soon as it's ready. Stay tuned, I hope to share lots of exciting new things here over the next few weeks.
0 notes
Text
Xcode MapView: Offsetting the compass and legal link
When creating an app that uses location-based content, it is common to include a full-screen map to display content. According to Apple's guidlines, you may not obstruct the "legal" link in the lower lefthand corner of the map. Additionally, if you want your users to be able to rotate the map, a compass appears in the upper right hand corner. This is a great feature, unless you want to use that portion of the screen for some other UI.
I believe that most users expect to be able to rotate the map, so to disable rotation makes an app feel limited. But if you want to use custom transparent UI elements in your app, you may find yourself needing to adjust the offset of the compass and legal link.
One would expect to find a compassInset and legalInset property for an MKMapView, however Apple apparently thought that would be too easy.
If you add your own custom elements to your view however, you may see something like this (notice the legal button is obscured by the bottom toolbar, and the compass is barely visible underneath the navigation bar)
This is because adding elements like these manually does not update the topLayoutGuide and bottomLayoutGuide properties, and the mapView does not know it needs to offset it's subviews. To fix this, we can create an NSObject that follows the UILayoutSupport protocol, and manually override the topLayoutGuide and bottomLayoutGuide values:
@interface MapLayoutGuide : NSObject <UILayoutSupport> @property (nonatomic) CGFloat insetLength; -(id)initWithLength:(CGFloat)length; @end @implementation MapLayoutGuide @synthesize insetLength = _length; - (id)initWithLength:(CGFloat)insetlength { self = [super init]; if (self) { _length = insetlength; } return self; } @end
And within the view controller displaying the map:
- (id)topLayoutGuide { // #define kCompassInset 128.0/2.0 return [[MapLayoutGuide alloc] initWithLength:kCompassInset]; } - (id)bottomLayoutGuide { // #define kLegalInset = 44.0 return [[MapLayoutGuide alloc] initWithLength:kLegalInset]; }
And there we have it! It's not as simple as [mapView setCompassInset:kCompassInset], but it works without having to search through the subviews of the map and manually adjust them. If anyone comes up with a cleaner way to accomplish this, I'd love to hear about it!
0 notes
Text
Country Perfume on iPad Pt. 2
Country Perfume 4.0 is now available on the app store!
As I began to write about earlier, the biggest change in this version is iPad compatibility. I've developed a few iPad apps before, but the process I used was incredibly messy. I made multiple storyboard files, and a different view controller file for the iPad and iPhone versions.
To help keep things simple this time around, I decided to keep the same sort of UI in place, instead of switching to a split view controller. This allowed me to use autoresizing to fit the app to the iPad's screen, without having to make a separate view controller file for each device.
Here are the main things I learned since my last post:
1. A UIDynamicAnimator can get confused when the screen changes size 2. Frame vs. Bounds 3. The asset catalog in Xcode 5 is the bee's knees
Let's start at the top of that list:
#1: UIDynamicAnimator and screen rotation
In Country Perfume, I utilize UIKitDynamics to apply the bouncing gravity effect to the bottom area. When I scaled the interface to the iPad screen, I suddenly encountered a problem with the bottom view not sizing properly when the screen rotated:
The width was being adjusted properly, but it was offset in the -x direction by the change in screen width. After some experimenting, I finally discovered that my UIDynamicAnimator wasn't able to respond properly to the rotation, even though the view containing the animated view was working properly. To fix the problem, I remove the behaviors from the UIDynamicAnimator when the view is about to rotate, and add the behaviors back when the rotation completes. This essentially "pauses" the animator while the rotation is occuring.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [animator addBehavior:bottomViewBehavior]; [animator addBehavior:collisionBehavior]; [animator addBehavior:gravityBehavior]; } -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [animator removeAllBehaviors]; }
#2 - Frame vs. Bounds
Up until this point, I had always used view.frame.size to size subviews in all of my apps. However, I was encountering problems and soon found that the frame of the superview doensn't change with orientation, wheras the bounds do. Using the bounds of my superview fixed many sizing issues. This illustrates the output when rotating the screen from portrait to landscape on an iPad mini:
NSLog(@"Frame: %@", NSStringFromCGRect(self.view.frame)); NSLog(@"Bounds: %@", NSStringFromCGRect(self.view.bounds)); CountryPerfume[192:60b] Frame: {{0, 0}, {768, 1024}} CountryPerfume[192:60b] Bounds: {{0, 0}, {768, 1024}} CountryPerfume[192:60b] Frame: {{0, 0}, {768, 1024}} CountryPerfume[192:60b] Bounds: {{0, 0}, {1024, 768}}
#3 - The asset catalog in Xcode 5 is the bee's knees
...Really. It's a fantastic thing. No more cryptic file names, and you can tell at a glance if you are missing an image size. As most of my assets were re-sized for the iPad screen, this made keeping them organized very easy.
0 notes
Photo
Some shots I took of STS-135, the last Space Shuttle launch in 2011. You can bet the day we launch humans again, I'll be there to see it. One of the most inspiring things I have ever witnessed.
1 note
·
View note
Text
Here's to 2013
I normally don't write things like this. I don't enjoy living in the past, reminiscing about better other times. But this has been a year worth writing about. Job losses changes, friends leaving moving, and questionable exciting career decisions made 2013 interesting, to say the least.
This year I read my name on Core77, was interviewed by Lynne Rossetto Kasper on the Splendid Table, made one of the first projects for the LEAP Motion controller, started an LLC, began sharing a studio space with two of the most driven and creative people I have ever met, and helped start a design collective that has met damn near every week since January 14th.
I have done more to be proud of in 2013 that in all my previous years combined, and my one New Year's resolution is to say the same thing about 2014 this time next year.

0 notes
Text
Country Perfume on iPad
After re-discovering my iPad last week, and seeing my family get a retina iPad mini for christmas, I felt like it was about time for me to work on an iPad app again. Or, more specifically, a universal app. Even more specifically, updating Country Perfume for the iPad.
I've encountered moderate success so far. I've changed my database structure slightly, incorporating a to-many relationship to connect a farm to its cheeses. This allows me to easily keep track of the data that should currently be displayed on the screen by keeping track of only the selected farm. I also discovered the time-saving capacity of the code snippet library, and added my first snippet, a simple if-else structure to determine if the app is running on an iPad or an iPhone:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { // iPad } else { // iPhone / iPod touch }
The biggest headache I am currently encountering is how to deal with portrait and landscape orientations. I am utilizing UIKitDynamics to add a bouncing effect to the bottom view. In previous versions, I was adding UICollisionBoundaries manually:
[collisionBehavior addBoundaryWithIdentifier:@"Top" fromPoint:CGPointMake(0, self.view.frame.size.height - bottomView.frame.size.height) toPoint:CGPointMake(self.view.frame.size.width, self.view.frame.size.height - bottomView.frame.size.height)];
However, i could not find an easy way to move these boundaries when the screen rotates, so instead I decided to subclass a UIView to hold the collision boundaries, and have that view resize:
[bottomContainerView setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth]; animator = [[UIDynamicAnimator alloc] initWithReferenceView:bottomContainerView]; collisionBehavior = [[UICollisionBehavior alloc] init]; [collisionBehavior setCollisionMode:UICollisionBehaviorModeBoundaries]; [collisionBehavior setTranslatesReferenceBoundsIntoBoundary:YES]; [collisionBehavior addItem:bottomView];
This worked fine, but then I realized it was intercepting all touch events over my map. In order to make it pass the touches through (except when interacting with the list of cheeses), I did some googling which led me to the following technique:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // Return false to allow touches to pass through return (point.y > bottomView.frame.origin.y); }
Here, I simply test to see if the touch occurred above the bottom bar, indicating that the user actually intended to touch the map.
Finally, I noticed that as the iPad rotates, I was seeing content appear in the corners as the screen rotated. The views that I place at the top and bottom of the screen are actually quite tall, and just have an offset applied to them. To hide them , I simply added the following within viewDidLoad of my main view controller:
// Set clips to bounds to keep a black background when the view rotates [self.view setClipsToBounds:YES];
This line prevents the following image from ocurring (the yellow and tan portion in the upper left, and the green in the lower right should not be visible):
I am having trouble with one subview that just doesn't want to resize properly. It takes on the correct width, however it also gets offset in the -x direction at the same time... I am sure there is a simple soltion for this, but it has eluded me today.
All in all, this has been a fairly straightforward modification so far, and I hope to be done tomorrow evening, in time to submit it when iTunesConnect opens back up.
0 notes