Sugarcube
Some sugar for your cocoa. RubyMotion helpers.
Install / Use
/learn @rubymotion-community/SugarcubeREADME
SugarCube
About
Cocoa and CocoaTouch are verbose frameworks. These extensions hope to make development in rubymotion more enjoyable. With SugarCube, you can create a color from an integer or symbol, or create a UIFont or UIImage from a string.
Many core classes are opened up as well, like adding the '<<' operator to a
UIView instance, instead of view.addSubview(subview), you can use the more
idiomatic: view << subview.
The basic idea of SugarCube is to turn operations on their head. So instead of:
UIApplication.sharedApplication.openURL(NSURL.URLWithString(url))
How about:
url.nsurl.open
DISCLAIMER
It is possible that you will not like SugarCube. That is perfectly fine! Some people take milk in their coffee, some take sugar. Some crazy maniacs don't even drink coffee, if you can imagine that... All I'm saying is: to each their own. You should checkout [BubbleWrap][] for another take on Cocoa-wrappage.
CONTRIBUTIONS
SugarCube is the result of the hard work of many developers, but it’s mostly maintained by [Colin Gray][colinta], with help from members of the RubyMotion community. If you have an idea, please open a pull request so we can discuss it! All PRs must be submitted with specs.
If you use SugarCube on your projects, please consider donating a small amount via gratipay.com, or better yet: fork the project, add some specs, and improve the quality of this super-handy gem!
Documentation
A work in progress. This README is the best source, but I am trying to be more diligent about adding Yard documentation, which is available here:
http://rubydoc.info/gems/sugarcube/latest
Versioning
SugarCube uses FerVer: https://github.com/jonathanong/ferver. This means that minor breaking changes occur in minor version bumps, and sometimes a non-breaking change occures in the major version (like when we added OS X support).
Installation
gem install sugarcube
# in Rakefile
require 'sugarcube'
# or in Gemfile
gem 'sugarcube', :require => 'sugarcube-classic'
# or for the bold:
# gem 'sugarcube', :require => 'sugarcube-all'
# or for the picky:
# gem 'sugarcube', :require => [
# 'sugarcube',
# 'sugarcube-repl',
# ]
# in terminal
$ bundle install
Packages
SugarCube has grown over time to be a pretty massive collection of helpers.
While some people choose to use the entire library, other people like to pick
and choose the extensions they want to use. With that in mind, SugarCube is
written so that it does not pollute any classes by default. So if all you do
is require "sugarcube", you are NOT going to get much mileage!
In the installation code above, I show the example of using :require => 'sugarcube-all'
to include all of SugarCube's extensions. You can, alternatively require just
the packages you need:
Gemfile
gem 'sugarcube', :require => [
'sugarcube-ui',
'sugarcube-events',
'sugarcube-gestures',
'sugarcube-568',
'sugarcube-attributedstring',
]
Or, from your Rakefile:
$:.unshift('/Library/RubyMotion/lib')
require 'motion/project/template/ios'
require 'bundler'
Bundler.require
require 'sugarcube-ui'
require 'sugarcube-events'
require 'sugarcube-gestures'
require 'sugarcube-568'
require 'sugarcube-attributedstring'
You can require the packages in piecemeal like this, or you can require a group
of packages: classic, common, or all.
sugarcube-classic: Excludes 568, attributedstring, gestures, repl, awesome, anonymous, unholy, and legacysugarcube-common: Excludes awesome, anonymous, unholy, and legacysugarcube-all: Excludes legacy
So without further ado,
SugarCube
Packages are sorted more-or-less by their usefulness. The more esoteric ones are at the end.
REPL (wiki)
If you install SugarCube and only use the REPL package, you will benefit from some of SugarCube's greatest tricks!
require 'sugarcube-repl'
This package is useful during development because it adds methods to the REPL that make adjusting and introspecting views much easier. You'll get a lot more done in the REPL with these additions.
You should NEVER use these methods in your application, because this package is only included in 'development' mode. That means if you hard-code a call to 'tree' in your code, that will crash when you go to release your app. YIKES.
To keep this document lean-and-mean, I've put most of the REPL documentation in the wiki, but here's a quick overview:
-
Use the
treecommands to output your view hierarchy. It can accept a UIView,UIViewController, orCALayerobject as the root object, or it defaults to your application'sUIWindowobject.(main)> tree 0: . UIWindow(#6e1f950: [[0.0, 0.0], [320.0, 480.0]]) 1: `-- UIView(#8b203b0: [[0.0, 20.0], [320.0, 460.0]]) 2: +-- UIButton(#d028de0: [[10.0, 10.0], [320.0, 463.400512695312]]) -
The number can be passed to the
adjustmethod, aliased toa, and that will become the view or object you are adjusting.(main)> a 2 => UIButton(#d028de0: [[10.0, 10.0], [320.0, 463.400512695312]]) -
Now you can modify that view, either by accessing it via
a(with no arguments it returns the object being adjusted) or by using an adjust method:> up 1 > wider 15 # these have shorthands, too > u 1 > w 15 -
Changed your mind? undo all adjustments to the object currently selected:
> restore -
Which element in the tree did I select with adjust? You can make the object selected flash in the simulator:
> blink
Be sure to read more in the REPL Additions Wiki page.
UI on iOS: UIKit extensions (wiki)
A big package chock full of methods to make working in UIKit a joy.
require 'sugarcube-ui'
A few varieties of methods are in this package:
- Conversions:
'string-to'.uiimage,image.uiimageview,'string-to'.uilabel(font) - Helpers: shorthands for common operations, like
a_view << a_subview,a_subview.convert_frame_to(a_view) - Symbols:
:system.uifont(20),:label.uifontsize - Frame accessors:
a_view.x,a_view.x = 100(onUIViewandCALayer)
There are too many methods to define here. Instead: a complete list of methods is available in the documentation, and the wiki page is a great source as well.
UI on OS X: AppKit extensions
Similar extensions as the iOS version, but using the ns prefix on method names:
- Conversions:
'string-to'.nsimage,image.nsimageview,'string-to'.nslabel(font) - Helpers:
view << subview - Symbols:
:white.nscolor,:system.nsfont - Frame accessors:
a_view.x,a_view.x = 100(onUIView,CALayer,NSWindow, andNSScreen)
UI on Android
(warning: extending built-in classes is not reliable in RubyMotion on Android)
ViewGroup gets the same << method that you see in UIView and NSView.
Constants
require 'sugarcube-constants'
There are lots and lots of constants in UIKit, so many that I wanted a way to
write these as symbols instead of UILongConstantNames. This package adds
methods to Symbols to convert them into a UIKit or Foundation constant.
:center.nsalignment # => NSTextAlignmentCenter (formerly UITextAlignmentCenter)
:upside_down.uiorientation # => UIDeviceOrientationPortraitUpsideDown
:rounded.uibuttontype # => UIButtonTypeRoundedRect
:highlighted.uicontrolstate # => UIControlStateHighlighted
:touch.uicontrolevent # => UIControlEventTouchUpInside
:change.uicontrolevent # => UIControlEventValueChanged
:all.uicontrolevent # => UIControlEventAllEvents
# these are really handy for custom buttons - touch_start means the finger is
# inside the button, touch_stop is outside the button or canceled
:touch_start # => UIControlEventTouchDown | UIControlEventTouchDragEnter
:touch_stop # => UIControlEventTouchUpInside | UIControlEventTouchCancel | UIControlEventTouchDragExit
:large.uiactivityindicatorstyle # :large, :white, :gray
:bar.uisegmentedstyle # :plain, :bordered, :bar, :bezeled
# UITableView and UITableViewCell have LOTS of associated constants... I'm
# adding them as I come across them.
:automatic.uitablerowanimation # or .uitableviewrowanimation
:default.uitablecellstyle # or .uitableviewcellstyle
:disclosure.uitablecellaccessory # or .uitableviewcellaccessorytype
:blue.uitablecellselectionstyle # or .uitableviewcellselectionstyle
See the complete list by browsing the documentation, or open up symbol.rb.
Timer
require 'sugarcube-timer'
Methods get added to the Fixnum class, and are available as methods on
NSTimer, and can be called via the SugarCube::Timer module.
# once
1.second.later do
@view.shake
end
# repeating
1.second.every do
@view.shake
end
# you can assign the return value (an NSTimer)
timer = 1.second.every do
@view.shake
end
# and invalidate it
timer.invalidate
# the `every` method is available in the SugarCube::Timer module,
# which you mi
