Been pushing some new stuff to sugarcube recently, thought I would let anyone interested in on the new features. I'm using it on a *real* project these days, and as I need shorthands & aliases, this is where I put 'em. I also grabbed some ideas from this list and BubbleWrap.
My usual disclaimer: sugarcube has some odd notions that, while _I_ (and some others) find them beneficial, might not be appealing to you.
I recommend you NOT use sugarcube if you don't like it. :-P
sugarcube's paradigm shift is that it extends base types to perform higher-level operations, or to become a UIKit or Foundation object.
e.g. "FontName".uifont(20) # => UIFont.fontWithName("FontName", size:20)
Changes since 0.1
1) It's a real gem now! require 'sugarcube'
2) NSUserDefaults get/set
3) NSURL additions
4) CoreGraphics coercion functions (Rect, Size, Point)
5) UIView animation methods (fade_out, move_to, delta_to)
6) NSNotification - post notifications from any string
7) Easy frame adjustment for the REPL - this is very useful during development!
# NSUserDefaults
I'm not going to defend this, it looks outright bizarre, I know. It's exemplary of sugarcube's "backwards" style.
NSUserDefaults |
| 1 | :key.set_default(['any', 'objects']) | | 2 | # => NSUserDefaults.standardUserDefaults.setObject(['any', 'objects'], forKey: :key) | | 3 | :key.get_default | | 4 | # => NSUserDefaults.standardUserDefaults.objectForKey(:key) |
|
There *is* an advantage, though, which is that it is obvious what is getting saved.
Possible advantage? |
| 1 | App::Persistance[:test] = { my: 'test' } | | 2 | App::Persistance[:test][:my] = 'new' # nothing is saved. bug? | | 3 | | | 4 | :test.set_default { my: 'test' } | | 5 | :test.get_default[:my] = 'new' # nothing is saved, but more obvious(?) |
|
# NSURL
"
http://github.com".nsurl.open => `open` method on an NSURL calls NSUIApplication.sharedApplication.openURL(NSUrl.URLWithString(url))
# CoreGraphics
The objects output by `view.frame` are not the prettiest - and are they arrays or objects? structs? is it CGMakeRect or CGRectMake? BAH.
These are namespaced in SugarCube::CoreGraphics, so use `include SugarCube::CoreGraphics` to make them more easily accessible.
CoreGraphics |
| 1 | # wrap frame and such in a "pretty" object | | 2 | f = Rect(view.frame) | | 3 | o = Point(view.frame.origin) | | 4 | s = Size(view.frame.size) | | 5 | | | 6 | # create them easily | | 7 | f = Rect(x, y, w, h) | | 8 | f = Rect([[x, y], [w, h]]) | | 9 | | | 10 | # in many different ways! | | 11 | o = Point(x, y) | | 12 | s = Size(w, h) | | 13 | f = Rect(o, s) | | 14 | | | 15 | # and yes, they can be assigned (they are Array objects in the end) | | 16 | view.frame = f |
|
# UIView animations
Need a fade out? move a view across the screen? I'll add more (I want a "shake" animation already) as needed/wanted.
UIView animations |
| 1 | # default timeout is 0.3 | | 2 | view.fade_out { |view| | | 3 | view.removeFromSuperview | | 4 | } | | 5 | # options: | | 6 | view.fade_out(0.5, delay: 0, | | 7 | options: UIViewAnimationOptionCurveLinear, | | 8 | opacity: 0.5) { |view| | | 9 | view.removeFromSuperview | | 10 | } | | 11 | # move to position 0, 100 | | 12 | view.move_to([0, 100]) | | 13 | # move over 0, down 100, from current position | | 14 | view.delta_to([0, 100]) |
|
# NSNotification
NSNotification |
| 1 | "MyNotification".post_notification | | 2 | "MyNotification".post_notification(obj) # uses `obj` as the context, or something like that... | | 3 | "my notification".post_notification(obj, user: 'dict') | | 4 | # => NSNotificationCenter.defaultCenter.postNotificationName("my notification", object:obj, userInfo:{user: 'dict'}) |
|
# Frame Adjustments in the REPL - NEAT!
One thing I find myself doing a lot, since I don't use Xcode, is pixel-pushing views. sugarcube has a nifty way to make this less painful, even when you can't cmd+click on the right view.
These methods are namespaced by default, but if you `include SugarCube::Adjust` in app_delegate.rb (or wherever you need it - depends on the compilation order I think...) you can use them during development, and remove that later if you don't need it anymore, of if those methods are conflicting.
Sugarcube::Adjust example |
| 1 | # (In the REPL) | | 2 | # cmd-click on a view - but it might not be the view you want, in which case | | 3 | # you'll need to traverse it using superview & subviews | | 4 | > adjust superview.subviews[4].subviews[1] | | 5 | > up 1 | | 6 | > down 1 # same as up -1, obviously | | 7 | > left 1 | | 8 | > right 1 # same as up -1, obviously | | 9 | > origin 10, 12 # move to x:10, y:12 | | 10 | > wider 10 | | 11 | > thinner 1 | | 12 | > taller 1 | | 13 | > shorter 1 | | 14 | > size 100, 10 # set size to width:100, height: 10 | | 15 | > restore # original frame is saved when you call adjust | | 16 | | | 17 | # short versions! and let's assume I ran `include SC` | | 18 | > a superview.subviews[4].subviews[1] # this is not uncommon in the REPL | | 19 | > u # up, default value=1 | | 20 | > d # down | | 21 | > l # left | | 22 | > r # right | | 23 | > o 10, 12 # origin, also accepts an array (or Point() object) | | 24 | > w 10 # wider | | 25 | > n # thinner | | 26 | > t # taller | | 27 | > s # shorter | | 28 | > z 100, 10 # size, also accepts an array (or Size() object) | | 29 | > r # restore | | 30 | | | 31 | # if you forget what view you are adjusting, run `adjust` again | | 32 | > a | | 33 | => {UITextField @ x: 46.0 y:214.0, 280.0×33.0} child of UIView |
|