2014-02-17

My iPad app is available: Veronica's Garden Tracker


Please tell every gardener you know about Veronica's Garden Tracker for iPad. Thanks!

I aimed to create a good, simple, visual journal to be used on home vegetable gardens. I got the idea when I asked my wife a few years back, "Sweetie, what is this sprouting here?" and she had forgotten and her labels were missing, so we had to wait a few weeks until the plants got bigger to find the answer.

Google AdWords redeem coupon code screen has moved.

It took me a bit to find the new location to redeem those promotional codes that Google hands out to lure in folks like me into using AdWords. All the blogs out there talk about the old, easier-to-find location. Even the email that contains the promo code itself is wrong.
  1. Starting from AdWords home.
  2. Click gear icon in upper right.
  3. Click Billing from drop down menu.
  4. Click Transaction history.
  5. Click More Actions button.
  6. Click Apply a promotional code from the drop down menu.
  7. And there you are!



2013-12-11

Order that UIScrollViewDelegate methods get called when a user does a sloppy tap.

Please note that the UIScrollView I am using has pagingEnabled set to YES.

To create the sloppy tap gesture, the user makes the most minor drag motion possible with his finger. I call this a "sloppy tap" because about 1 in 10 of my own taps trigger this gesture on my iPad 2. Visually, the scroll view will not appear to move.

  1. scrollViewWillBeginDragging:
  2. scrollViewDidEndDragging:willDecelerate:
Note that scrollViewDidEndDecelerating: will not be called because no scrolling actually happened.

Here is what gets called when a user properly flicks his finger horizontally to scroll to a new page.

  1. scrollViewWillBeginDragging:
  2. scrollViewDidScroll: × ~4
  3. scrollViewDidEndDragging:willDecelerate:
  4. scrollViewDidScroll: × ~24;
  5. scrollViewDidEndDecelerating:
Suppose you want a flag toggled as soon as movement starts, and then you want it toggled again only after movement stops. There isn't one method you can count on for the second flip.

I already toggle the flag in scrollViewWillBeginDragging: and scrollViewDidEndDecelerating:. The solution is to also toggle the flag in scrollViewDidEndDragging:willDecelerate: when decelerate is NO.

I would have figured this out sooner if I had read the documentation more closely.

2013-12-06

lldb and Objective C: printing structs contained in objects.

I'm tired of looking up how to do this.

Wrong:
(lldb) expr -- self.scrollView.frame
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: 2 errors parsing expression
(lldb) expr -- (CGRect)self.scrollView.frame 
error: unsupported expression with unknown type
error: unsupported expression with unknown type
error: C-style cast from 'unknown type' to 'CGRect' is not allowed
error: 3 errors parsing expression

Correct:
(lldb) expr -- (CGRect)[[self scrollView]frame]
(CGRect) $5 = origin=(x=0, y=0) size=(width=768, height=607)

You'll notice I don't bother with gdb aliases like p. Please accept my apologies.

2013-12-05

[CALayer isKindOfClass:]: message sent to deallocated instance -- Get this error when using UINavigationController.

This is a tough one to debug, and I did not find many examples out there on solving this.

I was getting this error when manipulating my Navigation Controller stack via pushViewController. Here are the recreation steps:

  1. Due to user action, ViewControllerSubclassA instance X gets pushed to Navigation Controller stack.
  2. Due to user action, instance X pops itself from stack.
  3. Due to user action, ViewControllerSubclassA instance Y gets pushed to Navigation Controller stack.
  4. Crash happens!

There are going to be a thousand different reasons out there for this to occur, but I wanted to document my particular one in order to help.

I narrowed things down to which view by testing the app. I noticed that the crash only happened after I had tapped in a text field owned by ViewControllerSubclassA. Was a reference to a UITextField owned by a view controller still hanging around after the view controller was popped from the navigation controller stack? I added a debug line to find out.

2013-12-05 10:20:19.504 MyApp[82746:70b] -[MATypeAViewController viewDidLoad] [Line 50] CALayer of textField = CALayer: 0xefe5dd0
2013-12-05 10:20:27.373 MyApp[82746:70b] *** -[CALayer isKindOfClass:]: message sent to deallocated instance 0xefe5dd0

Yep, it sure was.

Removing this UITextFieldDelegate protocol method from my view controller solved the problem.

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
    if ([textField.text length] == MATextFieldIllegalLength)
    {
        return NO;
    }
    return YES;
}

What I guess was happening was that at times, NO was returned from this method, but the view controller popped itself from the stack anyway. This left a reference somewhere to the UITextField even though it got deallocated when its view controller went away.

2013-12-02

Jeff's first rule of programming.

Number of known software defects with an as-yet-unknown root cause of the type Boolean semantic error figured out per 1 km jogged while casually considering said defect: 1.

2013-11-21

UIColor HSB/HSV 360 degree to 0.0 thru 1.0 decimal conversion and bc.

As we all know, UIColor's method colorWithHue:saturation:brightness:alpha: maps the hue argument to a value between 0.0 and 1.0. Out in the real world, this is a value from 0 to 360. So after I'm done color shopping, I use bc to convert the hue values to the proper range from the UIKit framework. Unfortunately, I left bc with my usual scale value of 3.

Yes, a 5th grader would quickly realize how bad my mistake was, but I'm no 5th grader. It took me a while.

An example:

scale=3
(1/360) * 140
.280
scale=5
(1/360) * 140
.3878

Yikes! No wonder everything looked funny.