UITableView: Arrange Custom Model Objects (Without Core Data) in Sections

It is fairly simple to display data in sections in a tableview, if you’re using Core Data and NSFetchedResultsController. But if you have any amount of dynamic data and you want to do this using your own model object system, it is surprisingly not so.

However, it just takes a few additional lines of code to achieve this, and here’s how.

You will need a few additional variables in your tableViewController.

@property (strong, nonatomic) NSMutableArray *sectionsArray;
@property (strong, nonatomic) NSMutableArray *subArrays;

Next, in viewDidLoad:

//Load your model objects in an array:
NSArray *yourData = ... ;

// Extract the values for section titles from your model. [yourData valueForKeyPath:@"path"] extracts only the particular attribute we want into a new array, with which we create an NSSet, so that only unique objects remain. Assuming we want 'categories' as sections:

NSSet *set = [NSSet setWithArray:[yourData valueForKeyPath:@"category"]];

// Create a sortDescriptor in case you need to sort section names
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES selector:@selector(caseInsensitiveCompare:)];
	
self.sectionsArray = [NSMutableArray arrayWithArray:[[set allObjects]sortedArrayUsingDescriptors:@[sort]]];
self.subArrays = [NSMutableArray array];
	
//Iterate over each section, and fill with member objects.  

[self.sectionsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
		NSString *category = (NSString*)obj;
// For each section, identify all objects that contain the keyPath we used earlier
		NSArray *subArray = [self.historyArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category = %@",category]];
		NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
		
		subArray = [subArray sortedArrayUsingDescriptors:@[sort2]];

// The subarray is filled with arrays of member objects, each array at an index corresponding to the index of the section.
		[self.subArrays insertObject:subArray atIndex:idx];
	}];
[self.tableView reloadData];

Then setup the tableView, and that’s it:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return self.sectionsArray.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    NSArray *subArray = [self.subArrays objectAtIndex:section];
    return subArray.count;
}

-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
	return [self.sectionsArray objectAtIndex:section];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
	NSArray *subArray = [self.subArrays objectAtIndex:indexPath.section];
	Model *object = [subArray objectAtIndex:indexPath.row];

	cell.textLabel.text = object.title;

    return cell;
}

Favorites Library iOS app for Twitter Coming Soon

As someone who uses Twitter as a news reading and curating tool, I find the Favorites feature to be indispensable. While there are some online tools that archive or save these favorites in bookmarking services , I found that there are no satisfactory mobile services or apps, to access and search through these favorites on the go. Hence Favorites Library.

With Favorites Library:

  • Access and Search through Twitter Favorites from multiple accounts, offline.
  • Filter for Tweets containing Links or Pictures specifically. View all pictures in a gallery mode.
  • Optionally backup your Favorites archive to dropbox, and sync multiple devices. (While this may seem like an unnecessary feature – this is a client for an online service after all – remember that the number of tweets returned by the Twitter API is limited. There is a chance that some of your older favorites might drop off the radar, and so, a backup option)

Some screenshots:

Fav Library 1Fav Library 2     Fav Library 3

 

Look for Favorites Library to hit the App Store soon.

Highlight UIImageView Images on Touch

Supposing you have a UITapGestureRecognizer attached to a UIImageView, and you’d like your users to know that the image is tappable, a good way to do so is subtly highlight the image when it is touched.

UIImageViews have a setHighlightedImage method that can be used, but only if your image is static, and therefore you can create the ‘highlighted’ image in advance.

Instead, to achieve the effect we’d like, we need to subclass UIImageView. Override the following methods in the subclass:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

self.alpha = 0.8;

}

 

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{

//The touch may be cancelled, due to scrolling etc. Restore the alpha if that is the case.

self.alpha = 1;

 

}

 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

//Restore the alpha to its original state.

self.alpha = 1;

}

 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

 

}

 

Touching the UIImageView will now make it somewhat transparent. (The touchesMoved method is left blank, as suggested by the Apple docs – when overriding any of the above methods without calling super,  the other methods must be implemented, even if they are only stubs. Also note that userInteractionEnabled needs to be set to yes after initializing the imageView.)

To create a highlighted overlay effect, simply change the background color of the UIImageView to, say, black, in its init method.

Now simply change your existing UIImageViews to instances of your custom subclass (works inside TableView Cells also) , to enable the highlighting effect.

iOS: Add Subview With Animation

Took me sometime to figure this, but the UIView animateWithDuration.. methods do not animate adding/removing/showing/hiding of a view’s subviews. To do this, you need to use:

[UIView transitionWithView:self.containerView
duration:0.2
options:UIViewAnimationOptionTransitionCrossDissolve //any animation
animations:^ {

//remove existing view, and add a new subview
[self.subView removeFromSuperview];
[self.containerView addSubview:self.newSubView];

}
completion:nil];

Load Web Pages in Readability-Mode in Your App

Adding a WebView to display external links in your app is trivial, but if you want to offer more to your users, you can provide them the option to load the same webpage as Readability.com’s text-optimized version.

They offer a easy to use (and very quick) API to return the optimized version, which you can incorporate in your app’s code. The APIs in question are nothing but URL schemes, which makes it that much easier to incorporate (no need for API keys or parsing JSON responses).

Continue reading

Quickipedia for Mac Free for a Limited Time!

Enjoy a beautiful, minimalistic client for Wikipedia, on your Mac, with Quickipedia – now free for a very limited time.

quickipedia

Get it while it’s hot, ’cause I will be increasing the price to $2.99 after this sale.

Oh, and, if you download and enjoy using the app, I’d really appreciate it if you could rate it/leave a review on the App Store :)

Get it here!

NSWindow Behavior like Twitter Mac App

A statusbar item is a quick way to access an app running on your computer, and is especially useful when your dock is set to auto-hide (which is the case on my Air, given the limited screen space available). Such an item is not switched-on by default of course – but you might want to provide one, depending on the nature of your application. There are some caveats to using NSStatusItem though, as mentioned in the Apple Docs, which you might want to go through first.

In this post, I will discuss using an NSStatusItem in conjunction with a proper Window based app, that replicates the behavior of the Twitter OS X app. I find that the Twitter app  provides the ideal behavior when using the status-item (when it is set to ‘show/hide window’ in the preferences):

Continue reading

iOS Tip: UITextField inside Dynamic Prototype / Dequeuable UITableViewCells

A quick tip if you are using a UITextField inside a Dynamic Prototype (or for that matter any cell, prior to iOS 5) UITableViewCell. You might find that as you scroll the table view, any text entered in the text-field disappears. While the Cell is dequeued and reused by the table view, the TextField obviously is not – hence the issue.

To avoid this problem, you need to implement a delegate method of UITextField (remember to first make your Controller the delegate of the text-field):

-(void)textFieldDidEndEditing:(UITextField *)textField

 

This method is called whenever a text-field loses firstResponder status (i.e it loses focus). You can set up this method such that whatever text is entered in the Text-Field is saved as an NSString instance variable of your class, when the text-field loses focus. Text entered in a currently firstResponder text-field will not disappear while scrolling.

-(void)textFieldDidEndEditing:(UITextField *)textField{


// stringVariable is an instance variable of the current class.

if (textField == self.textField) {

self.stringVariable = self.textField.text;

}

 

}

 

and in the cellForRowAtIndexPath method of the UITableView datasource protocol, you can use this variable to set the text of the TextField whenever the UITableViewCell is being redrawn. You need not worry about how this might affect the end-user’s experience, as getting and setting the text-field’s text will happen so fast as to not be perceptible.

Cocoa: Update-as-you-type Search Results Menu

In a Cocoa app I’m working on, I wanted to display search results to the user, beneath the search field, that updated as the user kept typing – not unlike the way Safari displays suggestions as you keep typing.

safari_search

You’d think there would be a way to do this using NSMenu, but as it turns out, if you popup a menu when you type in the search field, the latter loses focus, and you’re no longer able to continue typing. You’ll have to be content with setting up the menu as the search field’s searchMenuTemplate, which is shown to the user only when he clicks on the search button.

After a lot of digging around, this is what I was able to put together in order to achieve the UI I wanted.

Continue reading

JSON+ 1.1 Submitted to Apple [Promo Codes Inside!]

Last night, I submitted version 1.1 of my app JSON+ for iPhone/iPod Touch, to Apple for review.

New in this version are:

  • Support for HTTP Basic Authentication (for access to private resources) and Custom Headers.
  • Ability to open links within the app itself (previously, links were opened in Safari).
  • UI optimisations and tweaks. I now use PrettyKit for Navigation controls, as opposed to the default iOS look. Check out the screenshots for a taste.
  • Bug fixes (saw this coming, didn’t you)

 

iOS Simulator Screen shot 05-Jun-2012 8.51.20 PM

iOS Simulator Screen shot 05-Jun-2012 8.51.34 PM

iOS Simulator Screen shot 05-Jun-2012 8.51.46 PM

The update should be out early next week. In the meantime, here are some promo codes for version 1.0 of the app. Grab them while they’re still hot!

HTXWPHE9X3L4

HXKLLHHL33JY

NMA4EEKTTHFE

XPPJ7WMFK4YE

RE7KP46H9K4R