AdSense Mobile Ad

Showing posts with label cocoa. Show all posts
Showing posts with label cocoa. Show all posts

Monday, June 16, 2014

NSControlTextEditingDelegate Methods Are Not Called on a the Delegate of a View-Based NSTableView

I was developing a OS X Cocoa application and the time came to validate the text input by the user while editing cells of an NSTableView. My Cocoa-fu immediately suggested me to take advantage of the NSControlTextEditingDelegate protocol that specifies the following two methods to hook exactly where I need to:
  • control:textShouldBeginEditing:
  • control:textShouldEndEditing:

These two protocol methods are invoked on the delegate object. Everyday's Interface Builder outlet connection stuff, I thought, unaware I'd lose the rest of the day trying to have those method called. I then selected the text field in the editable column whose editing I wanted to be notified of:


Then I selected the Connection Inspector and connected the delegate outlet to the target object:


Finally, I implemented the two aforementioned methods on the delegate object, ran the application and... nothing happened!

The Official Documentation

I'll won't tell about the frustration I felt trying to do one of the simplest and most paradigmatic tasks in Cocoa programming: setting a delegate and implementing the corresponding protocol. Suffice it to say, I felt like I had some evident bug in front my eyes but could not notice it. Not immediately, not after a cup of tea or two, not after a hour diving into the documentation I could find.

I revised the documentation, outlets and the code over and over again, but I could not detect the problem. Then I noticed that I was not the only one struggling with this issue, although no solution was provided.

To make a long story short, the documentation I checked seemed confirmed the it should have worked, until I found especially after reading an official Apple Technical Q&A, number QA1551, titled Detecting the start and end edit sessions of a cell in NSTableView, stating the following:

A: How do I detect start and end edit sessions of a cell in NSTableView
In order to detect when a user is about to start and end an edit session of a cell in NSTableView, you need to be set as the delegate of that table and implement the following NSControl delegate methods:
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor;
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;
The table forwards the delegate message it is getting from the text view on to your delegate object using the control:textShouldEndEditing: method. This way your delegate can be informed of which control the text view field editor is acting on its behalf.

So, you should not set the editable field delegate but the table one! Fortunately, that was easy to change. I removed the connection to the delegate outlet in the text field and set the table one instead. I started the application and... nothing happened again!

At this point I felt at a loss and started to wonder whether some code in my application was interfering with the editing notification path. I created a new Cocoa application and quickly replicated the solution suggested in the Apple documentation but the result was the same: the delegate methods were not being called.

The Solution

The solution was simple, and fortunately not very different from what a Cocoa programmer expects: setting a delegate and implementing a protocol. But while the protocol was the correct one (NSControlTextEditingDelegate), the delegate was not. Better yet: they were not.

In fact, after some of tests I reached the following conclusions:
  • A cell-based NSTableView instance works as expected: setting the table delegate causes the NSControlTextEditingDelegate protocol methods to be invoked on it.
  • A view-based NSTableView instance (such as mine and almost surely most of the new NSTableView instances out there) required both the table and the field delegates to be set for the NSControlTextEditingDelegate protocol methods to be invoked.

I suspected that the aforementioned Apple Technical Q&A QA1551 document only considers the case of cell-based tables despite its date of publication: view-based tables were introduced in OS X 10.6, shipped two months before this document was issued. To dispel my doubts I decided to experiment with both kinds of table and found the behaviour described above, one for each different kind of table.

Nevertheless, and even though I dedicated a lot of time to skimming through the documentation, I was unable to find a mention of this issue in any other guide, API documentation or technical article from Apple. Even the very good Table View Programming Guide for Mac makes no mention of this "peculiarity" despite being a fairly common use case.

I hope this post helps anybody falling into the same trap to quickly solve his issues with getting NSControlTextEditingDelegate notifications to his table delegate.

Thursday, June 5, 2014

EMCCountryPickerController v. 1.3.0 Has Been Released

EMCCountryPickerController v. 1.3.0 has been released bringing the possibility of resizing the flags shown in the table cells automatically resizing the cell height.

Here is a screenshot showing flags resized to fit in a square of size 20:

Custom Flag Size - Sized to Fit into 20x20

and here is a screenshot showing flags resized to fit in a square of size 80:

Custom Flag Size - Sized to Fit into 80x80


To set the desired flag size, just use the controller's flagSize property:

countryPicker.flagSize = 80;

You can get the latest version using CocoaPods, by adding a dependency to your Podfile:

pod 'EMCCountryPickerController' ~> '1.0'

If you are already using EMCCountryPickerController, then you just need to update your pod repository index:

$ pod repo update

and then and update your outdated project dependencies running this command in the project root directory:

$ pod update

Enjoy.

Monday, June 2, 2014

EMCCountryPickerController v. 1.2.0 Has Been Released

EMCCountryPickerController v. 1.2.0 has been released bringing a new localisation in the Spanish (es) language:


You can get the latest version using CocoaPods, by adding a dependency to your Podfile:

pod 'EMCCountryPickerController' ~> '1.0'

If you are already using EMCCountryPickerController, then you just need to update your pod repository index:

$ pod repo update

and then and update your outdated project dependencies running this command in the project root directory:

$ pod update

Enjoy.

Tuesday, May 27, 2014

EMCCountryPickerController: A Country Picker View Controller for iOS

EMCCountryPickerController is a view controller I've built that lets you choose a country from a searchable list that includes all the countries assigned an ISO 3166-1 alpha-2 two-letter country codes.



EMCCountryPickerController is extremely simple to use:
  • It just has to be presented.
  • The user interacts with the user interface and selects a country.
  • The selection is communicated to a delegate, which dismisses the view controller and uses the results.
Comprehensive usage details, as well as a complete demo project, can be found in its GitHub repository.

This component features also has the following additional features:
  • Country name can be localised (some localisations are already provided, such as English and Italian).
  • Flag borders can be drawn and customised.
  • Flags can be optionally turned off.

The controller includes the flag of all the available countries, rasterised from a SVG file in the public domain. The controller is distributed with the BSD 3-clause license.

Installation

Besides grabbing the sources and the resource files from its GitHub repository, the quickest way to use the controller is using CocoaPods and adding a reference to the EMCCountryPickerController pod to your project Podfile:

pod 'EMCCountryPickerController', '~> 1.1'

Enjoy.