Top Alignment for Labels and Labels v. TextView

A UILabel is giving me problems because it needs to display a lot of text but is aligning vertically in the center of the field frame. I need it to align to the top. Knowing there would be a lot of text I made the label large – it’s constraints are equal to the view. So I thought I had a couple of different options – 1) make it a textView which is meant for multiple lines of editable text, or 2) hacks. “Hacks” means to add the max number of lines to 0 and set the label to “size to fit.” However, there were a couple of things I had wrong. First, I shouldn’t have made the label so large. The label size will automatically increase, so what I should’ve done is just set the label to the top of the view and as text continues the label automatically increases it’s size down. So that includes getting rid of it’s constraints for height so that it would initially be at the minimal height. That way it will always start at the top.

So then the question is, do I want a label or a textView? I would think a label because I don’t want the view to be editable. However, in my situation the super view of the label is a subview of a map. It’s a shelf on a map, so it doesn’t cover the entire page, meaning there will be text off the viewable frame of the phone. The text will have to be scrollable. Apple tells us:

Although these classes actually can support the display of arbitrary amounts of text, labels and text fields are intended to be used for relatively small amounts of text, typically a single line. Text views, on the other hand, are meant to display large amounts of text.

https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/UsingTextClasses/UsingTextClasses.html

Apple also tells us labels are for static text, and text views and text fields are for editable text.  What about for large amounts of static text?  It seems to be the case that text views are the best in this circumstance.  Just change the “editable” setting to false, either programmatically or in the interface builder.

Communication Patterns between View Controllers

In a project I’m working on with three other people we have a number of different view controllers that need to pass information to each other.  Being a bit of a rushed project we used many different ways to communicate between the controllers.  Most of them not optimal.

1. The first and maybe easiest way to transfer information or instructions to another controller is through a segue in the prepare for segue method. This only really works to pass the information forward to the destination controllersegue

2.Another and generally respectable way of passing information forward and back is through delegation.delegation

3.If you need to send information to multiple places, NSNotifications can be useful.notification

Then there are hacks and/or less desirable methods of communicating.

4. Datastore. So you have a datastore and it’s got all the info you need. Why not use it? A data manager is used to store information for use with APIs, for example. It’s not specific to passing information. You can use it, but it’s not it’s intended purpose. It’s a bit of a hack:datastore

5. KVO. I noticed Key Value Observer was mentioned on the web. This is meant as a way to have object properties notice other object properties. It’s not really used much anymore and was never really intended for use for View Controllers. Stick with NSNotifications.kvo

6. NSUserDefaults. Really? Well we did it in our app. But I’m not proud of it, and it was a question of time. A quick and dirty way to store information that’s accessible to everyone else. What a mess. nsuserdefaults

So for both NSUserDefaults and the datastore, why not use information that’s stored somewhere else? I think of it like this – in programming you can use all sorts of means to accomplish your goal. But in object oriented programming, for example, the whole point is to use classes, inheritance, and object structure. So why would you use a different sort of strategy in you coding? Likewise, if you’re trying to communicate information between controllers or objects even, why not use the structures that were developed to do so? Otherwise, you code will be a big mess.

In our project we have the same information being passed to the datastore, to core data, to an API, to NSUserdefaults. It’s a mess and easy to get everything mixed up and broken. If we do it the right way, we only need to have the information communicated one time in one place. So if you’re in a rush, sure do what you need to do to get the job done, but by all means, if you can do it right the first time you’ll save yourself a lot of trouble later.

Properties and memory management in Objective C, a review. Oh, and a note about atomic and nonatomic.

ARC (Automatic Reference Counting) takes care of a lot, but not all, of the job of memory managers for most iOS programmers.  In the olden days, i.e. 2011, all objects had to be manually handled with respect to telling the compiler how to handle them in memory.  Each object, or property was, and still is,  given a reference count, a count for each reference was made to it.  It was up to the coder to keep track of the reference count and allocate memory appropriately, leaving code very susceptible to human error.  The coder would have to use key words such as “retain,” “release,” and “dealloc.” Now no more.  Most of the process is automatic.

Now, we give each property a reference value of either “strong“, “weak“, or “copy.”  A “strong” reference means that the object is not destroyed regardless if it’s being used by another object.  A “weak” reference means that an object is destroyed unless it is being used by another object with a strong reference.

I’m going to use and example from Rypress to illustrate:

Say we have a Person and Car class:


// Person.h
#import <Foundation/Foundation.h>

@class Car;

@interface Person : NSObject

@property (nonatomic) NSString *name;
@property (nonatomic, strong) Car *car;

@end

Then in our main we have the following:

// main.m
#import <Foundation/Foundation.h>
#import "Car.h"
#import "Person.h"

int main(int argc, const char * argv[]) {
@autoreleasepool {
// Add person class with strong name property. No problem!
Person *john = [[Person alloc] init];
john.name = @”John”;

// Add car class with strong Person property. No problem… yet…
Car *honda = [[Car alloc] init];
honda.model = @”Honda Civic”;
honda.driver = john;

//But look – adding strong car property to Person… it’s a loop. Bad.
john.car = honda;

NSLog(@”%@ is driving the %@”, honda.driver, honda.model);
}
return 0;
}

So in this example, we have a Car class object and a Person class object.  Each car has a strong Person property and each Person has a strong car property.  This will cause a big problem – a memory leak.  This is specifically called a “Retain Cycle.”  retain-cycle

These strong connections refer to “ownership.”   The car object owns the person object and the person object owns the car object.  Memory management knows that as long as an object has a strong reference it will not be destroyed.  So, in our example, car.person means that the person property will not be destroyed as soon as the main method has run through, it will only be destroyed once the car object is destroyed.  Then the attached person object will also be destroyed with it.

But, in this example, we also have person.car as a strong reference.  Car will not be destroyed unless person is destroyed and person will not be destroyed unless car is destroyed.  The objects will persist.  Your processor can handle this if the properties are a couple of strings, but it’s really bad if it’s more than that.

So we also have the “weak” reference to solve this problem.  Best thought of as a parent-child relationship, the object who is the parent has a weak property.  We simply change the car’s reference to weak:

// Person.h
#import <Foundation/Foundation.h>

@class Car;

@interface Person : NSObject

@property (nonatomic) NSString *name;
//change to weak reference:
@property (nonatomic, weak) Car *car;

@end

The cycle is broken.  When the method ends and person.car is no longer being used, person is destroyed because only  car was pointing to it with a weak reference.  Memory management is allowed to destroy it.

But wait, there’s could be a problem.  What if car also had a weak reference to person?

// Car.h
#import <Foundation/Foundation.h>
#import “Person.h”

@interface Car : NSObject

@property (nonatomic) NSString *model;
//weak reference
@property (nonatomic, weak) Person *driver;

@end

Then memory will not retain anything and both values act like local variables.  They’re gone once the method is run.

 

But wait, that’s not all!  Xcode has an analyzer that will help you find memory leaks (in theory – I’ve had no experience with it helping).

Screen Shot 2015-07-30 at 12.29.39 PM

 

Oh and one more thing.  Atomic and nonatomic.  These refer to thread safety for multithreading environments.  Basically, for programming for the Mac use atomic.  For iOS use nonatomic.  These handle the situation where you have multiple threads accessing the same property simultaneously.  Conceivably this could be a problem but in reality – not really.  The atomic property locks the object from being accessed by both the setter and getter simultaneously.  Without multithreading this is not worth the memory and not useful, so use “nonatomic.”  In iOS, nonatomic is almost always used.

SpriteKit Particle Effects

I’m currently working on a game and used SpriteKit’s particle effects a very easy and useful tool to create… well, particle effects.  Effects like smoke, or fire or explosions, etc…

SpriteKit uses a base image (png file) as the smallest “particle” and gives the user the ability to alter the number of particles and the way the particles animate together.  It comes with eight preloaded effects:

The "Rain" particle effect
The “Rain” particle effect
The "Snow" particle effect
The “Snow” particle effect
The "Smoke" particle effect
The “Smoke” particle effect
The "Spark" particle effect
The “Spark” particle effect
The "Fire" particle effect
The “Fire” particle effect
The "Magic" particle effect
The “Magic” particle effect
The "Bokeh" effect
The “Bokeh” particle effect
"Fireflies" particle effect
“Fireflies” particle effect

 

All of these, except for the “Bokeh” effect, are using the same base image, the “spark.png” image:

The base "spark" image
The base “spark” image

 

Multiply that image by a couple hundred to a thousand, add blur, animation and coloring and you’ll get most of the particle effects.  The “Bokeh” effect uses the “bokeh.png” image as it’s base:

The "bokeh" base image
The “bokeh” base image

It’s blurred in the “Bokeh” particle effect and has a low alpha to make it semi-transparent then turned yellow.

You can also add your own image. In the following example I changed the spark image used for the “Snow” particle effect, to the “spaceship” png image( the “spaceship” image comes as a free demo in SpriteKit):

Changing from the "spark.png" to "spaceship.png" in the "Snow" particle effect.
Changing from the “spark.png” to “spaceship.png” in the “Snow” particle effect.

So that’s all well and good, but how about adjusting the effects? These base effects can be used to create explosions or bursts in games:

Burst effect from "Rain"
Burst effect from “Rain”
Explosion based off "Fire" effect.
Explosion based off “Fire” effect.

All this is done through the SKNode inspector:

SKNode inspector
SKNode inspector

The Particle Birth Rate and Maximum adjust how many particles come out at once, with the maximum limiting how many can come out within a lifecycle giving a pulsing effect.

 

The Lifetime Start and Range effect how long each particle will last and variation to that lifetime.

 

The Position range is how long the effect will stretch in the X and Y coordinates.

 

The Angle Start depends on your particle behavior but basically if you want a burst effect, like the sun or an explosion you would set the range to 360, as opposed to 180 degrees if you wanted the particles to spread out more in one direction.  The starting point is the first angle.

 

The Speed is how fast the particles move with the range giving a plus or minus to show variation.

 

Acceleration will have an effect like gravity (in the -y axis) or wind (in the x axis).

 

Alpha will effect the opacity of the particles, with the range and speed effecting how fast they transition between opacity.

 

Scale effects the size of the particles, again with the range effecting variation in particles.

 

Rotation will depend on your image file – if it’s a sphere then you won’t notice anything, but any other particle will rotate, so in theory you could use a snow flake image, or leaf and have them rotate.

 

Beyond that there are various color blending options to play around with and a gradient slider.  Clicking on the slider will add multiple gradient points, so it’s worth playing with.

 

Using all these options can be frustrating and fun, with many unexpected results.  You really have to play around with them to get the effects to work right, with some options not working well until other options are adjusted correctly.

 

Then add to your code with something like this (the main point is to use the SKEmitterNode):

 

SKEmitterNode *emitter = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"MyParticle" ofType:@"sks"]];
emitter.position = CGPointMake(x,y); //your custom code relating to where you want the effect.
emitter.name = @"explosion";
// ... etc
[self.addChild:emitter];

Hope this helps.  Thanks!

iOS stupidity checklist

So you’re app isn’t working and you know it’s just because you forgot some stupid little thing… Here’s a checklist:

1. Did you check the Project Settings and make sure the storyboard is listed as the main interface?Screen Shot 2015-06-22 at 11.05.56 AM

2. Did you create the appropriate controller class for the view?

3. Did you make sure that controller class is listed as the views’ custom class ‘class’?

Screen Shot 2015-06-22 at 11.13.35 AM.

4. Did you check to see if your reuse identifier is correct or being used in the tableView:CellsForRowAtIndexPath method?

5. Make sure you opened your project in it’s workspace, not just the project file.

6. Did you check that the initial view controller is set…

7. If using delegates set them to self in viewDidLoad, (if self is the delegate). Eg,

self.delegate = self;

8.  Make sure all your field or button or object references are invoking the right property. Eg,

NSString *someString = self.textField.text;

Not

NSString *someString = textField;

Basic iOS Custom Utilities Interface for adding border options

One of my assignments at the Flatiron School was  to program a blackjack game and make it work in views.  It went swimmingly except it looked like crap.  I used labels to make cards and the labels didn’t have borders.  I thought “surely Apple put border options in the utilities window, I mean their not savages!”  Alas, I was wrong.  But the option is definitely there programmatically.  I’ve found a number of ways online, but the simplest was to create a category of UIView in the project that creates an interface option so that all classes and subclasses of UIView now have a border option.  For the sake of the example I also added opacity and shadow radius. I’m not sure those additions are very practical except as an example. Essentially what we’re doing is unhiding options for the utilities uiinterface. So here’s how you do it:

As of writing this post we’re on Xcode 6.  So you create a new file>Objective C file>Name it what you want, for example “BorderOptions”, make sure it’s a subclass of “UIView”Screen Shot 2015-06-14 at 9.38.13 PM

Next add the following properties to the category header file:

[sourcecode language=”objc”]@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable NSInteger borderWidth;
@property (nonatomic) IBInspectable NSInteger cornerRadius;
@property (nonatomic) IBInspectable float opacity;
@property (nonatomic) IBInspectable CGFloat shadowRadius;[/sourcecode]

Then, in the .m implementation file add this:

[sourcecode language=”objc”]@dynamic borderColor,borderWidth,cornerRadius;
-(void)setBorderColor:(UIColor *)borderColor
{
[self.layer setBorderColor:borderColor.CGColor];
}

-(void)setBorderWidth:(NSInteger)borderWidth
{
[self.layer setBorderWidth:borderWidth];
}

-(void)setCornerRadius:(NSInteger)cornerRadius
{
[self.layer setCornerRadius:cornerRadius];
}

-(void)setOpacity:(float)opacity
{
[self.layer setOpacity:opacity];}

-(void) setShadowRadius:(CGFloat)shadowRadius
{
[self.layer setShadowRadius:shadowRadius];
}
[/sourcecode]

The methods here use our class’s super-class, UIView, methods.  So instead of defining new getters, we just have to tell Xcode to use the super-class’s getters.  We do this by inserting the line

[sourcecode language=”objc”]
@dynamic borderColor, borderWidth, cornerRadius[/sourcecode]

@dynamic tells the compiler just that – it tells Xcode that all these methods are methods in the super-class, so just use the super-classes getters.

Now in the attributes inspector you will have an option to set border color, radius and thickness:
Screen Shot 2015-06-14 at 9.46.02 PM

That’s it!

But what does it mean? Well that’s a little more complicated.  To see the full story is beyond the scope of this post and written more completely by Apple’s developers here:

Creating custom views that render in interface builder

*My simple answer was primarily taken from:

stackoverflow

 

 

Xcode: How to make the viewController a set size

When the viewController is first dragged onto the storyboard it defaults to a strange box size.  There are a number of different ways to set the viewController size to more useable dimensions.

 

1. The first is to uncheck the size class option:

 

Screen Shot 2015-06-11 at 10.27.05 AM

Fig.1 – Utilities Window

Here you can see at the top I have the “File inspector” selected.  The next arrow shows the “Use Size Classes” checkbox deselected.  This will then give you another pop up asking if you want to disable size classes and which format screen you wish to use – iPhone, iPad, etc..  Doing this will set the size.  Big problems here though as you need to be able to have your app work with all the different size iOS devices.  With the “Use Size Classes” unchecked you won’t be able to program constraints which are needed once you are ready to use your app on anything but one size.

2.  When you first add the viewController, in the utilities window select the top “Size Inspector” and then select “Freeform” for simulated size.  The problem here is that you have to manually input the height and width.

3. Also you can use the “Attributes selector” in the top of the utilities window.  There, the top drop down menu gives you the option of a number of different sizes of screen.

Screen Shot 2015-06-11 at 11.50.40 AM

 

A coupe of major problems with this though.  In general, it’s better to not get used to the size on your computer screen and instead test it on your device.

5/14/15 Objective C

Coding progress:

As per usual when learning a new technology, at first I think I’m not getting it at all, and then all of a sudden it just works in my head.  Objective-C is transitioning to a better place.

Pointers?  I think, as far as I can understand, that it’s almost just like making all the variable types sort of like an array except that the notation is different and also the actual memory location is expressed.  Ok, so maybe I don’t quite get it yet.  I feel like I’m getting there.  In the meantime, I’m just adding *s to my variables.  It works.

Also, I’m getting used to the more verbose syntax of objective C and I approve, so far.  It makes sense to be clearer in the programming language and less reliant on comments.  We’ll see how I feel once I get to actually programming.

I’m studying a number of different things: Treehouse Objective C course, Stanford 2013 iOS Course (may be a little advanced for me but I’m just starting it), Udemy Intro to C programming, and Codeschool iOS.  Phew.  Not to mention pre-work for the flatiron bootcamp.

5/10/15  Coding bootcamp?!

Wow. It’s been a while.  I’ve been busy but unfocused. Going towards one technology then another (for example WordPress vs php vs  JavaScript). So I’ve had it. I’m done with self-study. I’m trying for a coding bootcamp. I’ve taught myself a fair amount of front end so I’m looking at learning iOS.  Based on a compiled language instead of scripted – objective-C vs Ruby/JavaScript. Also I want to really get a foundation in a language.  A lot of jobs there too.
So which boot camp?
In NYC there are two that I’m aware of that focus on iOS – Flatiron and TurnToTech. Both have their pluses and minuses. I’ve heard nothing but glowing reviews of flatiron. TurnToTech doesn’t have the reputation and also has a very different strategy – they give you a project and you have to figure it out. They don’t have teachers, just people there to help you if you don’t understand something. Ostensibly, like in real life.   Flatiron is $15000 and TurnToTech is $10000. That’s a sh*t ton. In both cases. They’re both too expensive but there’s not much of an alternative out there.  It’s hard to part with that much money especially when no one is actually teaching – can’t I do that on my own?  I’d be paying 10k just for a place to study and a mentor and I guess a curriculum. And that is correct.  And I want that at least. On the other hand, I have to pay 5k more at flatiron for a teacher plus a strong community. The bottom line is I need those things and if I want them I’ve got to pay. So, I’ve gotten over it -ish.
Ok. Now back to trying to figure out pointers.

1/27/15

So, my personal website is now live.  It’s not perfect but the best I can do for the moment.  I used javascript for the slideup effect but came across a way to do it with CSS only which is preferable.  Also need to do the fade effect with the footer slide which is was why I chose the effect but … When I get to it.

Now I’m adding more projects.  I just completed an overhaul of a comedy series website: http://www.scottanddave.net

I’m waiting for the go ahead from Scott then I will make it live.