Class: UIViewController

Inherits:
Object
  • Object
show all
Includes:
Teacup::Layout
Defined in:
lib/teacup/z_core_extensions/ui_view_controller.rb

Overview

Adds methods to the UIViewController class to make defining a layout and stylesheet very easy. Also provides rotation methods that analyze

Direct Known Subclasses

FirstController, LandscapeOnlyController

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Teacup::Layout

#layout, #stylesheet, #subview

Class Attribute Details

.layout_definitionObject (readonly)

Returns the value of attribute layout_definition.



7
8
9
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 7

def layout_definition
  @layout_definition
end

Class Method Details

.layout(stylename = nil, properties = {}, &block) ⇒ Object

Define the layout of a controller’s view.

This function is analogous to Teacup::Layout#layout, though it is designed so you can create an entire layout in a declarative manner in your controller.

The hope is that this declarativeness will allow us to automatically deal with common iOS programming tasks (like releasing views when low-memory conditions occur) for you. This is still not implemented though.

Examples:

MyViewController < UIViewController
  layout :my_view do
    subview UILabel, title: "Test"
    subview UITextField, {
      frame: [[200, 200], [100, 100]]
      delegate: self
    }
    subview UIView, :shiny_thing) {
      subview UIView, :centre_of_shiny_thing
    }
  end
end

Parameters:

  • name

    The stylename for your controller’s view.

  • properties (defaults to: {})

    Any extra styles that you want to apply.

  • &block

    The block in which you should define your layout. It will be instance_exec’d in the context of a controller instance.



42
43
44
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 42

def layout(stylename=nil, properties={}, &block)
  @layout_definition = [stylename, properties, block]
end

.stylesheet(new_stylesheet = nil) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 46

def stylesheet(new_stylesheet=nil)
  if new_stylesheet.nil?
    return @stylesheet
  end

  @stylesheet = new_stylesheet
end

Instance Method Details

#autorotateMaskObject



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 171

def autorotateMask
  if view.stylesheet and view.stylesheet.is_a?(Teacup::Stylesheet) and view.stylename
    properties = view.stylesheet.query(view.stylename, self, orientation)
    device = UIDevice.currentDevice.userInterfaceIdiom
    device == UIUserInterfaceIdiomPhone

    orientations = 0
    if properties.supports?(:portrait) or properties.supports?(:upside_up)
      orientations |= UIInterfaceOrientationPortrait
    end

    if device == UIUserInterfaceIdiomPhone
      # :portrait does not imply upside_down on the iphone
      if properties.supports?(:upside_down)
        orientations |= UIInterfaceOrientationPortraitUpsideDown
      end
    else
      # but does on the ipad
      if properties.supports?(:portrait) or properties.supports?(:upside_down)
        orientations |= UIInterfaceOrientationPortraitUpsideDown
      end
    end

    if properties.supports?(:landscape) or properties.supports?(:landscape_left)
      orientations |= UIInterfaceOrientationLandscapeLeft
    end

    if properties.supports?(:landscape) or properties.supports?(:landscape_right)
      orientations |= UIInterfaceOrientationLandscapeRight
    end

    if orientations == 0
      orientations |= UIInterfaceOrientationPortrait
    end
    return orientations
  end
  return UIInterfaceOrientationPortrait
end

#autorotateToOrientation(orientation) ⇒ Object

The compiling mechanisms combined with how UIKit works of rubymotion do not allow the ‘shouldAutorotateToInterfaceOrientation` method to be overridden in modules/extensions. So instead, HERE is the code for what `shouldAutorotateToInterfaceOrientation` should look like if you want to use the teacup rotation stuff. Call this method from your own `shouldAutorotateToInterfaceOrientation` method.

the teacup developers apologize for any inconvenience. :-)



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 137

def autorotateToOrientation(orientation)
  if view.stylesheet and view.stylesheet.is_a?(Teacup::Stylesheet) and view.stylename
    properties = view.stylesheet.query(view.stylename, self, orientation)

    # check for orientation-specific properties
    case orientation
    when UIInterfaceOrientationPortrait
      # portrait is "on" by default, must be turned off explicitly
      if properties.supports?(:portrait) == nil and properties.supports?(:upside_up) == nil
        return true
      end

      return (properties.supports?(:portrait) or properties.supports?(:upside_up))
    when UIInterfaceOrientationPortraitUpsideDown
      if UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPhone
        # iphone must have an explicit upside-down style, otherwise this returns
        # false
        return properties.supports?(:upside_down)
      else
        # ipad can just have a portrait style
        return (properties.supports?(:portrait) or properties.supports?(:upside_down))
      end
    when UIInterfaceOrientationLandscapeLeft
      return (properties.supports?(:landscape) or properties.supports?(:landscape_left))
    when UIInterfaceOrientationLandscapeRight
      return (properties.supports?(:landscape) or properties.supports?(:landscape_right))
    end

    return false
  end

  return orientation == UIInterfaceOrientationPortrait
end

#layoutDidLoadObject



125
126
127
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 125

def layoutDidLoad
  true
end

#stylesheet=(new_stylesheet) ⇒ Object

Assigning a new stylesheet triggers restyle!, so do this during a rotation to get your different layouts applied.

Assigning a stylesheet is an alternative to returning a Stylesheet in the stylesheet method. Note that restyle! calls stylesheet, so while assigning a stylesheet will trigger restyle!, your stylesheet will not be picked up if you don’t return it in a custom stylesheet method.

Examples:


stylesheet = Teacup::Stylesheet[:ipadhorizontal]
stylesheet = :ipadhorizontal

Returns:

  • Teacup::Stylesheet



70
71
72
73
74
75
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 70

def stylesheet=(new_stylesheet)
  @stylesheet = new_stylesheet
  if self.viewLoaded?
    self.view.restyle!
  end
end

#top_level_viewObject



77
78
79
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 77

def top_level_view
  return self.view
end

#viewDidLoadObject

Instantiate the layout from the class, and then call layoutDidLoad.

If you want to use Teacup in your controller, please hook into layoutDidLoad, not viewDidLoad.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 86

def viewDidLoad
  # look for a layout_definition in the list of ancestors
  layout_definition = nil
  my_stylesheet = self.stylesheet
  parent_class = self.class
  while parent_class != NSObject and not (layout_definition && my_stylesheet)
    if not my_stylesheet and parent_class.respond_to?(:stylesheet)
      my_stylesheet = parent_class.stylesheet
    end

    if not layout_definition and parent_class.respond_to?(:layout_definition)
      layout_definition = parent_class.layout_definition
    end
    parent_class = parent_class.superclass
  end

  should_restyle = Teacup.should_restyle_and_block

  if my_stylesheet and not self.stylesheet
    self.stylesheet = my_stylesheet
  end

  if layout_definition
    stylename, properties, block = layout_definition
    layout(view, stylename, properties, &block)
  end

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

  if defined? NSLayoutConstraint
    self.view.apply_constraints
  end

  layoutDidLoad
end

#willAnimateRotationToInterfaceOrientation(orientation, duration: duration) ⇒ Object



210
211
212
# File 'lib/teacup/z_core_extensions/ui_view_controller.rb', line 210

def willAnimateRotationToInterfaceOrientation(orientation, duration:duration)
  view.restyle!(orientation)
end