Skip to content
Colin T.A. Gray edited this page Jun 7, 2013 · 8 revisions

UIView

# add a subview
view << subview  # => view.addSubview(subview)
view.unshift(subview)  # adds subview to the bottom of the views

UIView.first_responder  # => returns the first responder, starting at UIApplication.sharedApplication.keyWindow
my_view.first_responder  # => also returns the first responder, but starts looking in my_view
my_view.controller  # => returns the UIViewController that this view belongs to

# convert to UIImage.  retina-ready.
my_view.uiimage
# that will use the `bounds` property to size the image.  but if you want a
# screen shot of the contents of a scroll view, pass in `true` or `:all` to this
# method.
my_scroll_view.uiimage(:all)

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 an attr_updates method, which creates an attribute identical to attr_accessor but the setter calls setNeedsDisplay if the new value != the old value.

class NiftyView < UIView
  attr_updates :insets, :pattern

  def drawRect(rect)
    # ...
  end
end

nifty_view.pattern = 'my_pattern'  # => setNeedsDisplay gets called
nifty_view.pattern = 'my_pattern'  # => setNeedsDisplay doesn't get called, because the value didn't change.

UIViewController

It is nice that any UIViewController can present a modal, but if you have tabs or navs or crap in the way, this is actually NOT what you want. You should use the rootViewController (whatever it may be) to present to modal.

And since this is a property on UIWindow, which is more-or-less a constant, we can make this the easiest to do!

include SugarCube::Modal  # make these methods available globally

view_ctlr = EditSomethingViewController.new
present_modal(view_ctlr)
# ...later, when all is well...
dismiss_modal

These accept completion blocks:

present_modal(view_ctlr) { puts "Now You See Me!" }
dismiss_modal { puts "Now You Don't!" }

If you like these methods, but you want to specify the reciever, they are re-defined on UIViewController for this purpose:

controller.present_modal(other_controller) { puts "presented" }

UINavigationController

push, << and pop instead of pushViewController and popViewController.

animated is true for all these.

pop accepts an argument: either a view controller to pop to, or the symbol :root which does what you might expect:

nav_ctlr << root_ctlr
# or nav_ctlr.push(root_ctlr)
nav_ctlr << new_ctlr
# ... imagine we push on a ton of controllers ...
nav_ctlr << another_ctlr
nav_ctlr << last_ctlr
nav_ctlr.pop # => pops to another_ctlr, because it's next on the stack
nav_ctlr.pop parent_ctlr # => pops to parent_ctlr
nav_ctlr.pop :root  # => pops to root_ctlr, because it's on the bottom

UITabBarController

I have mixed feelings about adding this extension, but I needed it, so maybe you will, too... Usually a UITabBarController has a static number of tabs, but in my case, I needed to be able to add one later, when a certain condition was met.

controllers = tabbar_ctlr.viewControllers
controllers << new_ctlr
tabbar_ctlr.setViewControllers(controllers, animated: true)

# =>

tabbar_ctlr << new_ctlr

UILabel

Added simple fit_to_size function to the label, which will start at the supplied font size and then squeeze down until all the text fits. This way you can assure any dynamic text will completely display in a given label frame.

The font size changes instead of the frame size.

# this will try to make the containing text fit at font size 40, but squeeze as needed.
@label.fit_to_size(40)
puts @label.font.pointSize # => Will be 40 or less depending on the font type and label frame.

CALayer

layer << sublayer  # just like UIView's << method

UIPickerView

picker_view[0]  # => picker_view.selectedRowInComponent(0)
picker_view[0] = 1  # => picker_view.selectRow(1, inComponent: 0, animated: true)

UIWebView

web_view.eval_js('alert("alerts are annoying");')
# => web_view.stringByEvaluatingJavaScriptFromString(...)

NSString

# UIImage from name
"my_image".uiimage  # => UIImage.imageNamed("my_image")

# UIFont from name
"my_font".uifont # => UIFont.fontWithName("my_font", size:UIFont.systemFontSize)
"my_font".uifont(20) # => UIFont.fontWithName("my_font", size:20)

# UILabel from string, can accept a font
lbl = "this is important".uilabel
lbl = "this is important".uilabel(UIFont.systemFontOfSize(20))

NSAttributedString

string = NSAttributedString.alloc.initWithString('HEY!', attributes:{NSFontAttributeName => UIFont.boldSystemFontOfSize(20)})
lbl = string.uilabel

Symbol

:bold.uifont  # UIFont.boldSystemFontOfSize(UIFont.systemFontSize)
:bold.uifont(10)  # UIFont.boldSystemFontOfSize(10)
:small.uifontsize # => UIFont.smallSystemFontSize
:small.uifont  # => UIFont.systemFontOfSize(:small.uifontsize)
:bold.uifont(:small)  # UIFont.boldSystemFontOfSize(:small.uifontsize)
Clone this wiki locally