Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Jay 10:23 am on March 12, 2015 Permalink | Reply

    What’s new in iOS 8.2 

    Screen Shot 2015-03-12 at 10.44.02This release introduces support for Apple Watch, and also includes improvements to the Health app, increased stability and bug fixes.

    Apple Watch support

    • New Apple Watch app to pair and sync with iPhone, and to customize watch settings
    • New Activity app for viewing fitness data and achievements from Apple Watch; appears when Apple Watch is paired
    • Available on iPhone 5 and later

    Health app improvements

    • Adds the ability to select the unit of measurement for distance, body temperature, height, weight and blood glucose
    • Improves stability when dealing with large amounts of data
    • Includes the ability to add and visualize workout sessions from 3rd-party apps
    • Addresses an issue that may have prevented users from adding a photo in Medical ID
    • Fixes units for vitamins and minerals
    • Fixes an issue where Health data wouldn’t refresh after changing data source order
    • Fixes an issue where some graphs showed no data values
    • Adds a privacy setting that enables turning off tracking of steps, distance and flights climbed

    Stability enhancements

    • Increases stability of Mail
    • Improves stability of Flyover in Maps
    • Improves stability of Music
    • Improves VoiceOver reliability
    • Improves connectivity with Made for iPhone Hearing Aids

    Bug fixes

    • Fixes an issue in Maps that prevented navigating to some favorite locations
    • Addresses an issue where the last word in a quick reply message wasn’t autocorrected
    • Fixes an issue where duplicate iTunes purchased content could prevent iCloud restore from completing
    • Resolves an issue where some music or playlists didn’t sync from iTunes to the Music app
    • Fixes an issue where deleted audiobooks sometimes remained on device
    • Resolves an issue that could prevent call audio from routing to car speakers while using Siri Eyes Free
    • Fixes a Bluetooth calling issue where no audio is heard until the call is answered
    • Fixes a timezone issue where Calendar events appear in GMT
    • Addresses an issue that caused certain events in a custom recurring meeting to drop from an Exchange calendar
    • Fixes a certificate error that prevented configuring an Exchange account behind a third-party gateway
    • Fixes an issue that could cause an organizer’s Exchange meeting notes to be overwritten
    • Resolves an issue that prevented some Calendar events from automatically showing as ‘Busy’ after accepting an invite

    For information on the security content of this update, please visit this website:

  • Jay 11:57 am on February 3, 2015 Permalink | Reply

    How to implement context menus for cut/copy/paste in a UICollectionView 

    Screen Shot 2015-02-03 at 11.56.47

    By default a collection view cell is implementing a long press gesture recogniser. If activated the cell will bring up the familiar context menu for cut, copy and paste. It’s up to us to enable it, and it’s also up to us how to react to this menu. Here’s how we can do that.

    The following three methods are provided as commented stubs in the CollectionViewController template.

    Showing the Menu

    First we need to tell our class that the menu is to be shown:

    - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
    	return YES;

    Returning YES here will show the menu for every cell, but since we also get an indexPath, we could make decisions based on which cell has been tapped and make the menu show up conditionally.

    Next we need to decide which items we want to show:

    - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    	return YES;

    Returning YES here will show cut, copy and paste. We can make this conditional too, based both in the indexPath for each cell, but also based on the action parameter. Here’s a variation which will only show cut and paste, but not copy:

    - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
        // no copy option please
        if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) {
            return NO;
    	return YES;

    Menu Actions

    It’s up to us what happens when either of those menu items is selected by the user. We can either use the UIPasteboard to retrieve and store our values, or create a property and store out entire object in it. I only have an NSString value per cell and will use the UIPasteboard.

    This method is called when the user taps a menu item:

    - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
        // Cut
        if ([NSStringFromSelector(action) isEqualToString:@"cut:"]) {
            // grab our value
            NSString *value = [self.cellData objectAtIndex:indexPath.row];
            // copy object to pasteboard
            [UIPasteboard generalPasteboard].string = value;
            // remove item
            [self.cellData removeObjectAtIndex:indexPath.row];
        // Copy
        if ([NSStringFromSelector(action) isEqualToString:@"copy:"]) {
            // grab our value
            NSString *value = [self.cellData objectAtIndex:indexPath.row];
            // copy object to pasteboard
            [UIPasteboard generalPasteboard].string = value;
        // Paste
        if ([NSStringFromSelector(action) isEqualToString:@"paste:"]) {
            // grab our value
            NSString *value = [UIPasteboard generalPasteboard].string;
            // insert at current position
            [self.cellData insertObject:value atIndex:indexPath.row];
        // then reload the collection view
        [self.collectionView reloadData];

    It looks more complex than it really is: we first procure the value of our cell, and then add it to (or remove it from) the underlying data source. Typically it’s a mutable array or Core Data. Once the data is updated, we ask the collection view to reload its data which then makes the changes appear.

    That’s it!

  • Jay 12:48 pm on February 2, 2015 Permalink | Reply
    Tags: ,   

    How to build a UICollectionView in iOS 8 

    In this video I’ll show you how to build a UICollectionView from scratch in Xcode 6. The class is available for both iPhone and iPad since iOS 6. If you know how to build a UITableView then building a UICollectionView will be familiar to you.

    I’ll start with a single view application, delete the ViewController class and start fresh with a UICollectionViewController. Next I’ll add a custom class for the UICollectionViewController and UICollectionViewCell and then we’ll hook it up in the storyboard.

    By the end we’ll have a simple Collection View App which allows multiple selections. I’m going to use this project to build on with other features in the future.

    Custom CollectionViewController Class

    The template provides a few good starting points, but they need to be changed to work. First there’s the cell’s reuse identifier, conveniently added as a static at the top of the implementation file. It’s there so we only need to change this once in the file. Replace it with your own, and remember to make the same change in the storyboard:

    static NSString * const reuseIdentifier = @"Cell";

    Screen Shot 2015-02-03 at 11.11.03

    Next up is the viewDidLoad method. To make dequeuing cells easier, Apple have provided a registerClass method. If you don’t add your custom cell here, nothing will appear when you run the app. I found that simply commenting out the line works just as well.

    The reason they provide this is so that the dequeueCellWithIdendifier method knows which custom cell class to instantiate (prior to iOS 6 it returned nil, but that check is no longer necessary).

    I’m also adding multiple selections here, something that cannot be done in the storyboard.

    - (void)viewDidLoad {
        [super viewDidLoad];
        // EVIL: Register your own cell class (or comment this out)
        [self.collectionView registerClass:[YourCustomCell class] forCellWithReuseIdentifier:reuseIdentifier];
        // allow multiple selections
        self.collectionView.allowsMultipleSelection = YES;
        self.collectionView.allowsSelection = YES;


    Much like with UITableViews, we need to provide the number of sections, as well as the number of items in each section:

    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
        return 1;
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        return self.cellData.count;

    If you don’t provide the sections method, it is assumed that you have one section. Usually we’d have some data and would return a count of how many items we have rather than fixed values here.

    We also need to provide what’s in each cell. Here we can add data to labels, populate UIImageViews and many other things our collection view cells may need:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
        cell.textLabel.text = [self.cellData objectAtIndex:indexPath.row];
        return cell;


    With UITableViews there were four styles of table cells we could choose from out of the box. A collection view cell on the other hand is completely blank, and we’re expected to provide everything inside it. This means we need a custom UICollectionViewCell class for our project.

    Anything we drag into the prototype cell in the storyboard can be hooked up to that custom class and the configured in the above cellForItemAtIndexPath method. Make sure any outlets are defined in the cell’s header file.

    Cell Selections

    Collection view cells have several views layered on top of each other. At the bottom is the backgroundView and the selectedBackgroundView. These are not configured by default, but if we add our own views here, the cell knows how display selections.

    Above the background/selectedBackgroundView is the contentView, and on top of the contentView is where we can add out own outlets (like labels and images). If we leave the contentView’s background colour transparent, the views underneath will be visible, and hence selections are visible too.

    Here’s how to configure our custom cell with two colours for selection and deselection. I’m doing this in awakeFromNib, which is called as soon as our cell is instantiated:

    - (void)awakeFromNib {
        // standard background (deselected)
        UIView *bgView = [[UIView alloc]initWithFrame:self.bounds];
        self.backgroundView = bgView;
        self.backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blue"]];
        // selected background
        UIView *selectedView = [[UIView alloc]initWithFrame:self.bounds];
        self.selectedBackgroundView = selectedView;
        self.selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"pink"]];

    Demo Project

    The code I’m writing here is available as a demo project on GitHub:

  • Jay 12:40 pm on February 2, 2015 Permalink | Reply

    How to use UIPasteboard to share data with iOS 

    Screen Shot 2015-02-02 at 11.56.41

    UIPasteboard allows you to copy data to iOS and paste it back into your own or other apps. Think of copying text from a Pages document and pasting it into an email. That’s UIPasteboard hard at work.

    The class supports NSString, UIImage, NSURL and UIColor out of the box. You can add your own items to the pasteboard like this:

    NSString *myString = @"Hello";
    [UIPasteboard generalPasteboard].string = myString;

    To retrieve the value:

    NSString *myString = [UIPasteboard generalPasteboard].string;
    NSLog(@"%@", myString);

    The principle is the same for the other data types.

    Copying and Pasting multiple items

    Single values aside, UIPasteboard also has the ability to store the above data types as an NSArray. IF you had multiple values you’d like to add, you can use this:

    NSString *myString = @"Hello";
    NSString *myOtherString = @"again";
    NSArray *stringArray = @[myString, myOtherString];
    [UIPasteboard generalPasteboard].strings = stringArray;

    This works with strings, images, URLs and colors.

    Binary Data

    UIPasteboard can also handle binary data from an NSData object. Here’s how to set data:

    NSData *myData = [NSData dataWithContentsOfFile:@"myFile"];
    [UIPasteboard generalPasteboard] setData:myData forPasteboardType:@"yourUTI"];

    and to retrieve your data

    NSData *moreData = [[UIPasteboard generalPasteboard]dataForPasteboardType:@"yourUTI"];

    The dataForPasteboardType parameter is an NSString of your choosing so that you can identify it as your data. Apple recommend to use the reverse DNS structure like com.yourdomain.yourapp.yourdata.

    Creating your own Pasteboards

    If you don’t want to share data with the general iOS Pasteboard, you can create your own:

    UIPasteboard *myPasteboard = [UIPasteboard pasteboardWithName:@"FunkyPasteboard" create:YES];

    To retrieve values from it in other classes, instantiate it again and pass NO as the create parameter.

    The Find Pasteboard Myth

    According to Apple’s documentation, there’s also the Find Pasteboard. Legend has it that it holds the latest string from Spotlight search. We should be able to access it like this:

    UIPasteboard *findPasteboard = [UIPasteboard pasteboardWithName:UIPasteboardNameFind create:NO];
    NSString *latestSearch = findPasteboard.string;
    NSLog(@"%@", latestSearch);

    which sadly doesn’t work. Even though the object exists and is valid, all of its properties are always nil, no matter how are we search for things. It’s therefore best to forget the Find Pasteboard exists and never mention it again.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Password Reset
Please enter your e-mail address. You will receive a new password via e-mail.