Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Jay Versluis 9:05 am on April 21, 2014 Permalink | Reply
    Tags:   

    How to set a badge value on a UITabBarController item 

    Screen Shot 2014-04-21 at 08.53.48

    Each view controller has access to a UITabBarItem. This is only displayed if the current view controller is part of a UITabBarController. A UITabBarItem has a badge value which is that little red mark above icon and name to the tab bar item itself (as shown in the screenshot above: LIVE is currently the badgeValue of the tab bar item).

    Here’s how you can set the badge value:

    // set the tab bar value (any NSString will work):
    self.tabBarItem.badgeValue = @"LIVE";
    
    // make it disappear again
    self.tabBarItem.badgeValue = nil;
    
    // set it to a little red circle (no value, just an empty string)
    self.tabBarItem.badgeValue = @"";
    

    This approach will work if you have direct access to the class in the view controller. More commonly though you’ll have your own class embedded in a UINavigationController, in which case its tab bar item (and title) is shown on that tab.

    In which case you can access the tab bar item like this:

    // set badge value on your own nav controller
    self.navigationController.tabBarItem.badgeValue = @"LIVE";
    
     
  • Jay Versluis 11:24 am on April 18, 2014 Permalink | Reply
    Tags: UIEvent   

    How to implement a Shake Gesture in iOS 

    Shake Gestures are great for “Magic Eight Ball” type apps: the user shakes the device, then looks at the screen and finds some kind of message. Spooky! Apple have implemented it for clearing text input too – something I must admit I never really liked.

    To make your device react to a Shake Gesture you need to implement the following code in the View Controller you app displays. We nee to do this for every View Controller that needs to respond to the shake gesture.

    - (BOOL)canBecomeFirstResponder {
        return YES;
    }
    
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
        if (UIEventSubtypeMotionShake) {
            
            NSLog(@"I'm shaking!");
        }
    }
    

    First the View Controller needs to be able to be the “first responder”. Now that he can, he will receive all kinds of events from the app.

    We’re interested in the Motion Event, specifically when it’s finished. You can also check for when it started, which will react as soon as movement is detected (not so good for that Eight Ball App).

     
  • Jay Versluis 8:07 pm on April 17, 2014 Permalink | Reply
    Tags: Cocoa Bindings, , , ,   

    How to bind an NSArrayController to an NSTableView 

    Core-Data-IconIn this screencast I will show you how to bind a Table View to an Array Controller in Cocoa, using Xcode 5.1 and OS X Mavericks.

    We’re using Core Data to save our entries and – check it out – we’re not writing a single line of code!

    Cocoa Bindings is one of the most exciting features in OS X development for me, and I hope that one day it’ll find its way into iOS too.

    The project is also available on GitHub:

    I’ve written more about how to do this here:

     

     
  • Jay Versluis 8:18 am on April 16, 2014 Permalink | Reply
    Tags: , NSEvent, NSView   

    How to handle mouse events in OS X 

    Handling mouse events in OS X is very different from the way in which we’re used to dealing with touch events in iOS. Here’s how to do it:

    You must subclass an NSView and assign your class in the the xib file – much like you would subclass a UIViewController and assign your own in the storyboard. Every Cocoa Application has at least one view, found under the Window of your app (you may have to expand the Document Outline for this to show, it’s at the bottom left in Interface Builder):

    Screen Shot 2014-04-16 at 08.16.19

    Then in your own class you can track mouse events by implementing these functions among several others:

    // react to mouse events
    - (void)mouseDown:(NSEvent *)theEvent {
        
        NSLog(@"Mouse was clicked");
    }
    
    - (void)mouseDragged:(NSEvent *)theEvent {
        
        NSLog(@"Mouse is dragging");
    }
    
    - (void)mouseUp:(NSEvent *)theEvent {
        
        NSLog(@"Mouse was let go");
    }
    

    The Apple documentation also mentions that we should override the following method for our custom view to accept mouse events – but in OS X 10.9.2 I didn’t find this to make a difference:

    - (BOOL)acceptsFirstResponder {
        
        return YES;
    }
    

    First Mouse Event

    There is something called the “first mouse” event. This is called when an app or window not currently in focus is clicked on. Usually that window will ignore where you clicked and only bring the app or window into focus, and then reacts to mouse events.

    You can change this behaviour by overriding the following method:

    // accept first mouse events
    - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent {
        
        NSLog(@"Got first mouse event");
        return YES;
    }
    
     
  • Jay Versluis 7:54 pm on April 15, 2014 Permalink | Reply
    Tags: , UISplitViewController   

    How to show the Master View button in a UISplitViewController app 

    I was tinkering with an iPad version of one of my apps, when I noticed that the nav bar button that hides and shows the Master View Controller in portrait mode was no longer displayed. You know, the one that reads “Master” by default.

    This is a problem if my app starts in portrait mode, because there’s no way to bring this button back. The Split View Controller handles that button in its willHideViewController delegate method – which was seemingly never called upon startup (anymore).

    I can’t call that method manually on startup because I don’t have the parameters that call this method – but I did find a solution that forces the Split View to call this method:

    // bring back the Bike Tours button in portrait
    [self.splitViewController.view setNeedsLayout];
    

    Calling this somewhere in viewDidLoad doesn’t hurt your app – but it avoids having to solve The Case of the Disappearing Split View Button.

     
  • Jay Versluis 7:37 pm on April 12, 2014 Permalink | Reply
    Tags: , NSThread   

    How to execute a method on a background thread in iOS 

    To call something from a background thread we can use dispatch_async.

    This cryptic looking statement will throw something to a background thread while the main thread can deal with other functions. This is especially useful if a method would take a long time to return and would be blocking your app while it’s waiting for an answer.

    When your method comes back with a result if executes a block which can be used to react to that result.

    Consider this example:

    - (IBAction)mainQueue:(id)sender {
        
        // call this on the main thread
        [NSThread sleepForTimeInterval:3];
        int i = arc4random() % 100;
        self.title = [[NSString alloc]initWithFormat:@"Result: %d", i];
        
    }
    

    This method waits for 3 seconds and then presents a random number between 0 and 99. Hook it up to a button in the Single View Template. Then add a Date Picker. Don’t hook that one up though: just spin it with all your might, and then click your button to see what happens.

    The Date Picker stops rolling while your action sleeps, and continues to spin when it’s finished to present the result. Simon Allardice used this trick in his course on Lynda.com – well worth watching.

    Now hook up another button to the following method:

    - (IBAction)backgroundQueue:(id)sender {
        
        // call the same method on a background thread
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            [NSThread sleepForTimeInterval:3];
            int i = arc4random() % 100;
            
            // update UI on the main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                self.title = [[NSString alloc]initWithFormat:@"Result: %d", i];
            });
    
        });
    }
    

    This looks complicated, but thanks to Xcode’s code completion it’s easy to use wherever you need. Here’s what’s happening:

    We create a background queue and execute the same function as above. When it’s done we’ll grab the main queue (or main thread) again and update our UI element. This has to be done on the main thread. If you try it on the background thread it won’t work (it won’t crash either which is good to know).

    Try it out! You’ll soon be dispatching all kinds of things on a background thread!

    Here’s a fully working iOS 7 Demo Project on GitHub:

    I’ve written another article about this subject here:

     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel
Password Reset
Please enter your e-mail address. You will receive a new password via e-mail.