Monday, 11 November 2013

Custom UITableViewCells

I've decided to write a blog post about the best way to create a custom UITableViewCell using a xib. I haven't been able to find a tutorial that covers all the steps, and since this is a very common thing, I'm going to outline them here.

To start, I'm going to assume you have a project set up, and you have a view controller that contains a UITableView.

First thing you are going to do is create the cell.

1) Go File > New > File... > Cocoa Touch > Objective-C class.

2) In the "Subclass of" field, type UITableViewCell. In the "Class" field, type the name of your custom cell. Click next, and make sure to include it in your target.

3) Once the class file has been added, you can add the .xib. Go File > New > File... > User Interface > View. Make sure to name the view the same as your custom cell's class name (for organization purposes).

4) In the .xib, click on the view, and delete it. Then, from the Object Library (on the bottom right), drag a UITableViewCell onto the canvas.

5) Click on the cell in the document tree, then in the Identity Inspector (top right), type your custom cell's class name in the class field. It should autocomplete to the name.

6) In the .xib, click on "File's Owner". In the Identity Inspector, set the class to be your View Controller that contains the UITableView.

7) Now, In Assistant Editor mode, switch the second view to your ViewController.m class. It should be located under Automatic in the file tree. If you don't see it there, try clicking on "File's Owner" (the yellow cube on the left), and try again.

8) Connect the UITableViewCell in the .xib to your viewController class as an IBOutlet (control+drag from the cell to your .m file). Make sure to also import your CustomCell.h in ViewController.m.

9) Customize the UITableViewCell with UILabels, UIImageViews, etc, and make sure to connect everything to CustomCell.h, not the View Controller class. Make sure to add a custom identifier in the Identifier field in the Attributes Inspector. Also, make sure to name your views uniquely. If you were to name your UIImageView "imageView", the results are unexpected since UITableViewCell already has this property.

10) Now, we're going to make a UINib property to hold on to the nib so that we don't have to load it for every cell.

11) Now we're going to implement the two required UITableViewDataSource methods. They should look like this.

Run your app, and you should get something similar to the image below:

Monday, 5 August 2013

Sneak Peek at my new Music app

I'm working on a new music app that runs on iOS 7. Here's a few sneak peek screenshots of the app. 

Sunday, 16 June 2013

FacePic now in the App Store!

The premise of the app is combining pictures from the back and front cameras on your device to create a single image, which can be shared on multiple social networks.

The app has a very simple interface, and responds quite quickly. Look for it in the App Store here.

Saturday, 2 March 2013

AirBoard 2.0 Update

I've completed the 2.0 version of AirBoard. Key features include a new UI, more logic for the second screen display, and support for creating brackets. It's available in the AppStore right now: FULL or FREE.

The bracket creator works by setting up matches, and only advancing the tournament once all the matches have been completed. As you go through each match, completing it, the second screen scrolls to the next unplayed match. Eliminated contestants are stored at the bottom of the tableview.

Here's some screenshots of the app in action:

Sunday, 17 February 2013

AirBoard update coming soon

I've got an update for my scoreboard app AirBoard coming out soon. This new version supports better rankings, and the ability to turn a leader board into a single elimination bracket. I'm currently working on updating the assets, and once that's done I'll be submitting.

Monday, 21 January 2013

Hundreds - Next Riddle (59)

From my sources online, I determined that this riddle was a Vigenère cipher. Vigenère ciphers are similar to Caesar ciphers, except instead of the contacts 3 character shift, it has a shift that is based on a keyword. The keyword is repeated until it is the same length as the text to encode.  i.e. If LEMON was the keyword, you would repeat it like so


for a message like


Then, you take the location of each letter in the alphabet and add them together to get the new letter (it's explained more complexly on wikipedia, but this is what it boils down to). This would produce the following secret message:


Thus, to decode one of these, you simply need a keyword, and subtract the keyword's letters from the encoded message's. This is the ruby script I wrote to do this:

file ="vigenere.txt", "r")
cypher = file.gets

$key = {}
keyword = ARGV[0]

$letterArray = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]

string = ""
count = 0
cypher.each_byte { |i|
   if(i.chr == " ")
      string = string + " "
      keywordLetter = keyword.split('')[count%keyword.length]
      offset = $letterArray.index(keywordLetter)
      index = $letterArray.index(i.chr)
      string = string + $letterArray[(index-offset)%26]
puts "\n"+string+"\n\n"

The script takes a single argument, which is the keyword, and tries to decode the message. With that taken care of, all that was left was to guess the keyword. Judging by the previous messages, the keyword had something to do with a harp or a chord or something. I tried pretty much everything I could think of, and then tried RADIUS after looking at the cipher's achievements page. The secret message:

Being part of a bad riddle that nobody cares about.

Tuesday, 8 January 2013

Hundreds - Next Riddle (45)

This riddle looked more like the third riddle, where letter substitution was necessary. With my handy script, I began substituting letters for short words until they made sense. Pretty soon the solution popped out: "What do persistence and a golden harp have in common". Looks like the riddles are related somehow...