All posts by Charlie Cliff

Designing a Custom UITableViewCell with a XIB File

Here’s a quick little Got’cha that crops up when you’re making a custom UICollectionView Cell.

I like to design my custom cells with their own XIB files, so that I can edit them and set up their connection independent of their corresponding CollectionView of TableView class files. This level of abstraction just helps me to conceptualize my code.

But when doing this, it’s important to make the IBOutlet connections to the Cell object and not the File’s Owner, rather than the normal case of making those connections to the File Owner’s class.

So it’s important to keep in ming which connections need to made and to what.

Running in China

One of the most important things in any project, not just in software development, is to maintain a disciplined schedule. It’s absolutely critical to always have a set of goals and approaching deadlines in mind, at any stage of a program, and to gear your efforts to accomplishing those goals. I honestly think this is a productive attitude to have and it is key to keep yourself and your team members focused and driven.

But at times those approaching deadlines can get a little out of hand, and the need to meet a project’s planned schedule can become the cart that ends up in front of the proverbial horse. At these times, it might seem like a good idea to do one of two things: either to begin ejecting some of the project’s more ambitious features in the hopes that these can be included in a later version, or to produce “brute-force” solutions that meets all of the contractual obligations of the project but will inevitably require re-design in the future.

I’ve been in this situation several times over the course of my career thus far and have implemented both of the above solutions. I have been in the position of the developer that is pushing for more time and the position of the team lead that is pushing to get the product out the door on time.

When fighting for more time on a project, I’ve found myself recounting the same parable over and over again to guide myself and my colleagues.

A long time ago in Ancient China, the great scholar Lao-Tzu was spending the winter months with his family in the small village in which they made their home, with his wife, his children, and several students. As the snows thawed, the Emperor sent a message to Lao-Tzu, commanding him to present himself at the royal court at mid-summer. Always a loyal citizen, Lau-Tzu bid his wife and children farewell, and he set out on the road to the ancient capitol, accompanied by his students.

As the travelers neared the end of their journey, Lao-Tzu’s youngest pupil noticed that skies over their heads had begun to darken and the clouds had begun to thicken as if to rain. Lao-Tzu scowled; for, being early summer, they had begun their journey in the middle of the rainy season. Not wanting to be delayed on the road, Lao-Tzu urged his party on, all the while the clouds continued to grow thick and shaded.

After traveling a little further down the road, the group met a farmer, who was on his way home from working in his rice paddy. The great scholar Lao-Tzu stopped the farmer, and asked him how far he and his pupils were from the Imperial city. The farmer explained to the scholar that he was, in fact, only a few short leagues from the capitol. Reassured by the farmer’s statement, Lao-Tzu gave a long sigh, but the skies were growing even darker while he had spoken with the farmer.

Lao-Tzu turned once again to the farmer and asked the man if he thought that he and his group would be able to reach the shelter of the city before the summer storm broke.

The farmer gave the scholar a thoughtful look. He noted that the young men in Lao-Tzu’s retinue were burdened with papers and books, the sort that a true scholar would always carry with him wherever he traveled. The farmer saw this, and said to Lao-Tzu that he believed that the party would reach the city in time, as long as they did not move too quickly.

Lao-Tzu thanked the farmer, and he and his party continued down the road.

As they traveled, the clouds became so thick, that none of the sky beyond them was visible. Lao-tzu began to worry, and he quickened his pace. The wind began to blow strongly, and Lao-Tzu hurried even more, holding his scholar’s cap against his head as he walked. Lightning became visible in the distance behind the group, and Lao-Tzu moved faster still.

Eventually, the group topped the crest of a small hill and espied the walls and minarets of the capitol only a short distance away; and as they began to move down the hill towards the great gates, the first small drops of rain began to fall.

Lao-Tzu steadied his pack and began to jog rather hurriedly towards the great gate. His students breathed heavily, for their loads were not light and the wind was blowing against them.

The rain drops, that had been small and scattered only moments before, began to grow more substantial, but soon Lao-Tzu and his party were only a short distance from the gate.

As they hurried to reach shelter, the great scholar misplaced his foot on the road, and tumbled into the dirt, spilling his papers onto the ground.

The wind came on strongly, and carried the sheaves into the air. And as Lao-Tzu’s students stooped to help their master, the summer storm broke around them, drenching them all in the cold rain. The water soaked into their clothes and seeped into their baggage, ruining their precious books, scrolls, and notes.

And if they had not hurried so much, the great scholar would not have slipped, and the party would have made it to the city gates in time.

Whenever someone pushes me to meet some unreasonable deadline, I always think of this story of Lao-Tzu on the Chinese road, and it always helps to put things in perspective to me.

Sometimes, going as fast as you can is really the slowest option you have.

presentScene Error

So I’ve made this mistake twice recently, and anytime that happens I tend to thoroughly document my problem and it’s solution. It’ s a kind of “Fool me Once” Attitude.

So this neat little error occurs when I’ve made a new UIView and try to add a new SKScene to the ViewController. When you add an SKScene, you’ll use the SKView  presentScene method to do so. Normally, you’ll fetch the main view of your presenting UIViewContoller to do this, but when I’ve added a brand spanking new UIViewController to my project and then attempt to present an SKScene, I’ll get this error:

Shot-1

This error message pops up because we’re trying to send the presentScene selector to a UIView, instead of an SKView.

You see, when you make a new UIViewController it’s view object will default to an instance of UIView instead of an SKView.

Fixing this is pretty simple, though.

You just have to change the class of your new UIViewController’s view object in the interface builder to an SKView.

Shot-2

 

And now you’re ready to rock and roll!

Red Sun Prototype

It’s important to test early and test often in order to get the best product possible.

Prince Albert had one of the world’s largest diamonds, the Koh-i-Noor, repeatedly re-cut in order to get the perfect shine to it, and that’s what we’ll be doing with Project Red Sun. Unfortunately for Prince Albert, this constant re-cutting decreased the size of the diamond by 40%! So hopefully, we’ll have a better idea of when to stop polishing.

To do that, we’re working on a quick prototype app to test the trickiest bits of functionality (with a loveable Pirate Theme!).

We’ll keep you apprised of our prototype project and we edge our way closer to a successful launch!

 Fingers (and swords) crossed!

Using Two CollectionViews

Something I’ve noticed myself doing is that I’ve been needing to set up more than one Collection View in a View Controller. This isn’t something that happens a lot, but when it does, it’s good to have an example or two in your notes from which to work.

The only real new functionality is to add some If-Then Statements to some of our CollectionView Data Source Methods in order to check on which Collection View is requesting data.

- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {

    if ( view == collectionView1 ) {

// Return the Number of Cells in collectionView1

   }

    if ( view ==collectionView2) {

// Return the Number of Cells in collectionView2;

   }

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)view cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    if ( view == collectionView1 ) {

// Return the Cells in collectionView1

   }

    if ( view ==collectionView2) {

// Return the Cells in collectionView2;

   }

}

All in all, it’s pretty simple.

Apportable

It’s taken me quite a bit of work to get as proficient with iOS and Objective C as I am. I’m not going to downplay the amount of time and energy I’ve spent on my skills, while simultaneously working full-time and going to graduate school full-time. It’s hard.

But iOS captures only about 45% of the Mobile Platform market. Over half of Mobile Devices are running Android now, and every developer needs to be at least familiar with the language.

But that means another 8 months of sleepless nights while crawling through the introductory exercises of a new library. Doesn’t it? Nope.

There are plenty of tools to compile Objective C code to the Android Platform. I started working with the Apportable Engine.

I’m a little skeptical, but I’m optimistic that this will really cut-down on the Android learning curve, especially for Video Game Development.

I’ll be posting my progress and some of the more, memorable, bugs I run into while using the Apportable Engine in the hopes that it might make some people’s lives a bit easier.

Compiling to Android

I ran into a really interesting, some might say frustrating, quirk of the Apportable Engine.

In order to get XCode to compile on the Android OS, it turns out that you have to explicitly add any file or resource that your project is going to use to your project.

In order to do this, first navigate to the Build Phase Tab in you Project Navigator.

Then, in the Compile Sources Section you’ll have to manually add references to your Class files.

Apportable_Adding Code

Then, in the Copy Bundle Resources Section you’ll have to manually add references to you resource file.

Apportable_Adding Reseources

 

And that should clear up the error.

Out On Safari

For the last several years I’ve been a Google Chrome man.

I used to use Firefox until the Google published it’s own browser, and then there was a slow but steady transition from using primarily Mozilla’s browser to Google, and I’ve been using Chrome as my primary browser ever since.

One of the main things that I’ll use Google Chrome for is to work on what iOS Apps I’m currently working with, which lead this past week to something of a tiff between myself and the Apple Support Staff.

This weekend I began tinkering with In-App Purchases, which I feel every App developer eventually does. One of the things that is needed before one even begins cutting code is to register yourself with Apple and sign Apple’s various legal documents. So I sat down to read through Apple’s license agreements and fill out the various forms they require.

Only I couldn’t.

I couldn’t seem to enter any of my contact information, or banking information, or any of the sundry tidbits of personal data. For some reason, I was completely cut-off. I couldn’t even see their drop-down menus. I was utterly flummoxed.

This led me to call the Apple Support Team for their assistance; and after reading through the prescripted responses, they informed me that:

“iTune Connect may have limited functionality on browsers other than Safari”.

And I’ll be honest, this statement confused the hell out of me, because what I’d witnessed was not something that I would label “limited functionality”, it was “no functionality”. The site did not do what it was required to do. There is only one objective, and iTunes Connect doesn’t accomplish it in Chrome.

My mind boggles!

Although, I have to hand it to apple Support, no functionality is a hell of a limitation.

Positioning the Platforms – Y Now!?

Last time we nailed down the X-Coordinate of our Platform Nodes, and this time we’ll dig into the much more difficult task of picking a Y-Coordinate. In our last post, we just left the Coordinate as a value of 4, which will make a single unbroken platform. (Pretty boring right?)

But now it’s time to add a little challenge!

The primary aspect of platform games is the ability of the player to jump from one platform to another, essentially making an obstacles course. Sometimes there can be monsters, or treasures, or traps, but at their heart, platform games really come down to that simple premise.

So to procedurally generate this feeling, our first step is to start programmatically carrying the height of our platforms as they scroll across our screen.

To do this, we’re going to take some time to do a bit of design effort that will save us some time down the road.

What we’re going to do is add a new class to our project that encapsulates our height calculation algorithm. This design principle is called the Strategy Pattern, and is the best pattern to encapsulate complicated algorithm that might change over time. For now, we’ll be keeping our algorithm simple, but we may want to change it over time, and this design pattern will help make that easier.

So we’ll make a new class in our project and call it  EEPlatformGenerator.

Now that we have our strategy class, we can get to work.

But, there’s no sense getting ourselves wound around the axel immediately, so we’ll implement the simplest possible algorithm that we can. The simplest way to vary the height of our platforms is to just make it random. To do this, we’ll spin a quick helper function to generate a random number between two values, a maximum and minimum value:

Method - Random Number

Now all we have to decide what those maximum and minimum values are going to be. So we’re going add some data to our new class:

Class - EP Platform Method

What this data does is:

  1. currentBlockHeight – This datum will track the Block Height of the last platform.
  2. jumpHeight – This datum is the height our player can achieve when he jumps.
  3. dropHeight – This datum is the height form which a player can fall without taking damage.
  4. platformCielingHeight – This datum will provide the maximum height of a platform. We’ll use this to prevent our platforms from climbing to ridiculous heights, we wouldn’t want a platform with a height of 145,057.

Now we’ll use our new data to build a method to determine the height of our next platform:

Method - heightOfPlatform_01

 

Ta Da!!!