Differences since v0.13


SugarCube is slowly but surely growing it’s test folder. If you follow sugarcube on twitter (@sugarcube_rb) I post the output of rake spec now and then, though I just found out that the twitter commandline tool I’ve been using has been grossly negligent in posting so far.

As of now: 249 specifications (1065 requirements), 0 failures, 0 errors

The Usual Sugar

More Date Methods

“`ruby 1.millisecond || 2.milliseconds 1.millisec || 2.millisecs

relative to now, or another date

NSDate.new # => 2013-01-03 11:42:24 -0700 5.days.ago # => 2012-12-29 11:42:24 -0700 5.days.before(NSDate.new) # => 2012-12-29 11:42:24 -0700 5.days.hence # => 2013-01-08 11:42:24 -0700 5.days.after(NSDate.new) # => 2013-01-08 11:42:24 -0700


feb12013 = NSDate.from_components(year: 2013, month: 2, day:1) ”`

Number and Date, with style

“`ruby 10000.stringwithstyle 10000.stringwithstyle(NSNumberFormatterCurrencyStyle) # => ”$10,000.00" 10000.stringwithstyle(:currency) # => “$10,000.00”

now.stringwithstyle # => “February 19, 2013” now.stringwithstyle(NSDateFormatterShortStyle) # => “2/19/13” now.stringwithstyle(:short) # => “2/19/13” “`

NSData conversion (strings, images)

”`ruby stringdata = ‘String’.nsdata # => default encoding is UTF8. imagedata = ‘an image’.uiimage.nsdata # PNG data representation

stringdata.nsstring # => ‘String’ imagedata.nsimage # => whatever ‘an image’ was “`

Some more file operations


rm a file

“my.plist”.remove! # => “my.plist”.document.remove!

get the resource path


get the resource URL, useful for local HTML operations


access data from Info.plist

“CFBundleVersion”.info_plist “`

New Image Operations

”`ruby image.inrect(frame) # returns the part of the image contained in frame image.scaleto(newsize) # won’t stretch, but the image might have transparent padding image.scaleto(newsize, background: :white) # adds a white background before padding image.scalewithin(newsize) # same as scaleto in that it doesn’t stretch the

image, but the size is not guaranteed to be new_size. It is guaranteed not to

be bigger than new_size

image.scaletofill(newsize) # again, like scaleto, but the image is guaranteed

to completely fill new_size, even if some of the image has to be cropped to fit.

You can control which side or corner you prefer to remain visible. because the

aspect ratio is maintained, only ONE dimension will need to be cropped.

image.scaletofill(newsize, position: :topleft)

returns a UIColor (and supports retina images)

image.color_at([5, 5])

Apply a mask to an image. The mask should be a grayscale image. White areas

will be made transparent, and black opaque.


Combine two images

imageab = imagea << image_b “`

568 - 4” iPhone-specific images

If you require 'sugarcube-568' in your Rakefile, you can use UIImage.imageNamed(name) or name.uiimage to load images that are specific to the 4" iphone by using the suffix -568h, e.g. image-568h@2x.png

“`ruby ‘tall’.uiimage # => UIImage.imageNamed(‘tall’)

=> tall.png on iphone 3g

=> tall@2x.png on iphone 4

=> tall-568h@2x.png on iphone 5


This code is ported from https://github.com/gaj/imageNamed568, which I had some problems with on RubyMotion (it worked, but not always. Very strange).



convert a UIView to UIImage. retina-ready.


rotate animation

view.rotateto Math::PI # rotate view upside down view.rotateto(duration: 0.5, angle: 45.degrees) # using options ”`

When defining a UIView subclass, you often have attributes that affect your drawRect method (99% of the time, ALL the attributes affect drawing, right?). So SugarCube adds a attr_updates method, which creates an attribute identical to attr_accessor but the setter calls setNeedsDisplay if the new value != the old value.

ruby class NiftyView < UIView attr_updates :insets, :pattern end

This was pulled off warrenm’s AHAlertView project. I thought the effect was awesome, and deserved more attention!


ruby view.tumble # the view will fall and rotate - a good 'cancel button effect'

Animation Chains

These are used to create a string of animations:

ruby UIView.animation_chain { view.slide(:left, 20) }.and_then { view.slide(:up, 20) }.and_then { view.slide(:right, 20) }.and_then { view.slide(:down, 20) }.and_then { view.fade_out }.start

The gotcha is that you have to assign animation options (easing, duration, delay) multiple times. The options you pass to and_then do not get assigned to the animations within the block.

ruby UIView.animation_chain(duration:1) { view.slide(:left, size: 20, duration: 1) }.and_then(duration: 1) { view.slide(:up, size: 20, duration: 1) }

Not pretty, but the only solution I see is to assign the options to a class variable that all the animation methods would use. In the rare case that you create animations on separate threads, the options would get all messed up (and correct me if I’m wrong, but this does seem like a distinct possibility).

Okay, not the most exciting release, but I hope you enjoy nonetheless!