Module: Teacup::Layout

Included in:
CustomTeacupClass, UIView, UIViewController
Defined in:
lib/teacup/layout.rb

Overview

Teacup::Layout defines a layout and subview function that can be used to declare and configure the layout of views and the view hierarchy in your application.

This module is included into UIView and UIViewController directly so these functions are available in the places you need them.

In order to use layout() in a UIViewController most effectively you will want to define a stylesheet method that returns a stylesheet.

Examples:

class MyViewController < UIViewController
  stylesheet :logo

  layout(:my_view) do
    layout UIImage, :logo
  end
end

Instance Method Summary collapse

Instance Method Details

#layout(view_or_class, name_or_properties = nil, properties_or_nil = nil, &block) ⇒ Object

Alter the layout of a view

For example, to alter the width and height of a carousel:

Or to layout the carousel in the default style:

You can also use this method with #subview, for example to add a new image to a carousel:

Examples:

layout(carousel, width: 500, height: 100)
layout(carousel, :default_carousel)
layout(carousel) do
  subview(UIImage, backgroundColor: UIColor.colorWithImagePattern(image)
end

Parameters:

  • instance

    The first parameter is the view that you want to layout.

  • name

    The second parameter is optional, and is the stylename to apply to the element. When using stylesheets any properties defined in the current stylesheet (see #stylesheet) for this element will be immediately applied.

  • properties

    The third parameter is optional, and is a Hash of properties to apply to the view directly.

  • &block

    If a block is passed, it is evaluated such that any calls to #subview that occur within that block cause created subviews to be added to this view instead of to the top-level view.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/teacup/layout.rb', line 103

def layout(view_or_class, name_or_properties=nil, properties_or_nil=nil, &block)
  view = to_instance(view_or_class)

  name = nil
  properties = properties_or_nil

  if name_or_properties.is_a? Hash
    name = nil
    properties = name_or_properties
  elsif name_or_properties
    name = name_or_properties.to_sym
  end

  # prevents the calling of restyle! until we return to this method
  should_restyle = Teacup.should_restyle_and_block

  # assign the 'teacup_next_responder', which is queried for a stylesheet if
  # one is not explicitly assigned to the view
  view.teacup_next_responder = self
  view.stylename = name
  if properties
    view.style(properties) if properties
  end

  if block_given?
    superview_chain << view
    begin
      instance_exec(view, &block) if block_given?
    rescue NoMethodError => e
      NSLog("Exception executing layout(#{view.inspect}) in #{self.inspect} (stylesheet=#{stylesheet})")
      raise e
    end

    superview_chain.pop
  end

  if should_restyle
    Teacup.should_restyle!
    view.restyle!
  end
  view
end

#stylesheetObject

Returns a stylesheet to use to style the contents of this controller’s view. You can also assign a stylesheet to #stylesheet=, which will in turn call restyle!.

This method will be queried each time restyle! is called, and also implicitly whenever Teacup needs to draw your layout (currently only at view load time).

Examples:


def stylesheet
  if [UIInterfaceOrientationLandscapeLeft,
      UIInterfaceOrientationLandscapeRight].include?(UIInterface.currentDevice.orientation)
    Teacup::Stylesheet[:ipad]
  else
    Teacup::Stylesheet[:ipadvertical]
  end
end

Returns:

  • Teacup::Stylesheet



58
59
60
61
62
63
64
# File 'lib/teacup/layout.rb', line 58

def stylesheet
  if @stylesheet.is_a? Symbol
    @stylesheet = Teacup::Stylesheet[@stylesheet]
  end

  @stylesheet
end

#stylesheet=(val) ⇒ Object

Assign a Stylesheet or Stylesheet name (Symbol)

Examples:


stylesheet = Stylesheet.new do
               style :root, backgroundColor: UIColor.blueColor
             end
controller.stylesheet = stylesheet
# or use a stylename
view.stylesheet = :stylesheet_name

Returns:

  • val



34
35
36
# File 'lib/teacup/layout.rb', line 34

def stylesheet= val
  @stylesheet = val
end

#subview(class_or_instance, *args, &block) ⇒ Object

Add a new subview to the view heirarchy.

By default the subview will be added at the top level of the view heirarchy, though if this function is executed within a block passed to #layout or #subview, then this view will be added as a subview of the instance being layed out by the block.

This is particularly useful when coupled with the UIViewController.heirarchy function that allows you to declare your view heirarchy.

For example, to specify that a controller should contain some labels:

If you need to add a new image at runtime, you can also do that:

Examples:

MyViewController < UIViewController
  layout(:my_view) do
    subview(UILabel, text: 'Test')
    subview(UILabel, :styled_label)
  end
end
layout(carousel) do
  subview(UIImage, backgroundColor: UIColor.colorWithImagePattern(image)
end

Parameters:

  • class_or_instance

    The UIView subclass (or instance thereof) that you want to add. If you pass a class, an instance will be created by calling new.

  • *args

    Arguments to pass to #layout to instruct teacup how to lay out the newly added subview.

  • &block

    A block to execute with the current view context set to your new element, see #layout for more details.

Returns:

  • instance The instance that was added to the view heirarchy.



184
185
186
187
188
189
190
191
192
# File 'lib/teacup/layout.rb', line 184

def subview(class_or_instance, *args, &block)
  instance = to_instance(class_or_instance)

  (superview_chain.last || top_level_view).addSubview(instance)

  layout(instance, *args, &block)

  instance
end