-
Notifications
You must be signed in to change notification settings - Fork 66
UIKit
# 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)
# convert a view's frame to another view's coordinates. This method uses the
# frame: [[0, 0], subview.frame.size] because view.bounds is not always entirely
# reliable for what we're trying to do here.
subview.convert_frame_to(view)
view.convert_frame_from(subview)
# or just the origin
subview.convert_origin_to(view)
view.convert_origin_from(subview)
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.
As a convenience, the FrameAccessor methods (https://github.com/AlexDenisov/FrameAccessor) are mixed into UIView
. However, bottom
and right
are not added, because adding top
and left
would lead to basically reproducing all of geomotion.
view.frame = [[10, 20], [100, 200]]
view.x # => 10
view.x = 50
view.y = 30
view.y # => 30
view.width # => 100
view.height # => 200
Come on, Apple, this is just ridiculous:
button.setTitle('foo', forState: UIControlStateNormal)
# how about...
button.title = 'foo'
You're welcome! 😉 -colinta
You can push
(aka the <<
operator) and pop
view controllers onto the childViewControllers
array, these are overridden in classes that can define a more useful way of adding controllers, for instance the UINavigationController
animates the pushViewController
method.
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
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
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.
layer << sublayer # just like UIView's << method
picker_view[0] # => picker_view.selectedRowInComponent(0)
picker_view[0] = 1 # => picker_view.selectRow(1, inComponent: 0, animated: true)
web_view.eval_js('alert("alerts are annoying");')
# => web_view.stringByEvaluatingJavaScriptFromString(...)
# 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))
string = NSAttributedString.alloc.initWithString('HEY!', attributes:{NSFontAttributeName => UIFont.boldSystemFontOfSize(20)})
lbl = string.uilabel
: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)