Skip to content
Browse files

refactor view builder into smaller classes

  • Loading branch information...
1 parent 30f47b6 commit 155c1475ff28c1332467282d5154d29492cb848a Sean Ho committed May 15, 2012
View
15 README.md
@@ -17,7 +17,7 @@ Or refer to the blog post [Using 3rd Party Ruby Library in RubyMotion](http://re
def viewDidLoad
UI::Layout.setup(view) do
label width: 200, height: 20, text: "Choose your lucky word", color: UIColor.darkGrayColor
- image_view top: 50, left: 50, right: 50, image:UIImage.imageName("sample.jpg")
+ image_view top: 50, left: 50, right: 50, image: "sample.jpg"
end
end
````
@@ -37,6 +37,7 @@ end
````
### UIKit support
+- UIActivityIndicatorView via `activity_indicator`
- UIButton via `button`
- UIDatePicker via `date_picker`
- UIImageView via `image_view`
@@ -61,20 +62,16 @@ end
### Custom view support
````ruby
-def viewDidLoad
- UI::Layout.setup(view) do
- add CustomViewClass, name: "custom_view"...
- end
+UI::Layout.setup(view) do
+ add CustomViewClass, name: "custom_view"...
end
````
### View anchoring
````ruby
-def viewDidLoad
- UI::Layout.setup(view) do
- toolbar bottom: 10, left: 10, right: 10, anchors: [:left, :right, :bottom]
- end
+UI::Layout.setup(view) do
+ toolbar bottom: 10, left: 10, right: 10, anchors: [:left, :right, :bottom]
end
````
View
8 Rakefile
@@ -5,4 +5,12 @@ Motion::Project::App.setup do |app|
# Use `rake config' to see complete project settings.
app.name = 'SimpleView'
app.files += Dir.glob(File.join(app.project_dir, 'lib/**/*.rb'))
+ app.files_dependencies 'lib/builders/ui_control_builder.rb' => 'lib/builders/ui_view_builder.rb'
+ app.files_dependencies 'lib/builders/ui_activity_indicator_view_builder.rb' => 'lib/builders/ui_view_builder.rb'
+ app.files_dependencies 'lib/builders/ui_button_builder.rb' => 'lib/builders/ui_control_builder.rb'
+ app.files_dependencies 'lib/builders/ui_image_view_builder.rb' => 'lib/builders/ui_view_builder.rb'
+ app.files_dependencies 'lib/builders/ui_progress_view_builder.rb' => 'lib/builders/ui_view_builder.rb'
+ app.files_dependencies 'lib/builders/ui_segmented_control_builder.rb' => 'lib/builders/ui_control_builder.rb'
+ app.files_dependencies 'lib/builders/ui_table_view_builder.rb' => 'lib/builders/ui_view_builder.rb'
+ app.files_dependencies 'lib/builders/ui_table_view_cell_builder.rb' => 'lib/builders/ui_view_builder.rb'
end
View
8 lib/builders/ui_activity_indicator_view_builder.rb
@@ -0,0 +1,8 @@
+module UI
+ class UIActivityIndicatorViewBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ style = options.delete(:style) || UIActivityIndicatorViewStyleWhite
+ klass.alloc.initWithActivityIndicatorStyle(style)
+ end
+ end
+end
View
8 lib/builders/ui_button_builder.rb
@@ -0,0 +1,8 @@
+module UI
+ class UIButtonBuilder < UIControlBuilder
+ def view_for_class(klass, options = {})
+ button_type = options.delete(:buttonType) || options.delete(:button_type) || UIButtonTypeRoundedRect
+ klass.buttonWithType(button_type)
+ end
+ end
+end
View
7 lib/builders/ui_control_builder.rb
@@ -0,0 +1,7 @@
+module UI
+ class UIControlBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ klass.alloc.init
+ end
+ end
+end
View
29 lib/builders/ui_image_view_builder.rb
@@ -0,0 +1,29 @@
+module UI
+ class UIImageViewBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ image = extract_image(options, :image)
+ highlighted_image = extract_image(options, [:highlightedImage, :highlighted_image])
+
+ if image && highlighted_image
+ klass.alloc.initWithImage(image, highlightedImage:highlighted_image)
+ elsif image
+ klass.alloc.initWithImage(image)
+ else
+ klass.alloc.initWithFrame(CGRectZero)
+ end
+ end
+
+ def extract_image(options, key)
+ if key.is_a?(Array)
+ key.each do |k|
+ image = options.delete(k)
+ break unless image.nil?
+ end
+ else
+ image = options.delete(key)
+ end
+ image = UIImage.imageNamed(image) if !image.nil? && image.is_a?(String)
+ image
+ end
+ end
+end
View
8 lib/builders/ui_progress_view_builder.rb
@@ -0,0 +1,8 @@
+module UI
+ class UIProgressViewBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ style = options.delete(:style) || UIProgressViewStyleDefault
+ klass.alloc.initWithProgressViewStyle(style)
+ end
+ end
+end
View
8 lib/builders/ui_segmented_control_builder.rb
@@ -0,0 +1,8 @@
+module UI
+ class UISegmentedControlBuilder < UIControlBuilder
+ def view_for_class(klass, options = {})
+ items = options.delete(:items) || []
+ klass.alloc.initWithItems(items)
+ end
+ end
+end
View
8 lib/builders/ui_table_view_builder.rb
@@ -0,0 +1,8 @@
+module UI
+ class UITableViewBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ style = options.delete(:style) || UITableViewStylePlain
+ klass.alloc.initWithFrame(CGRectZero, style: style)
+ end
+ end
+end
View
9 lib/builders/ui_table_view_cell_builder.rb
@@ -0,0 +1,9 @@
+module UI
+ class UITableViewCellBuilder < UIViewBuilder
+ def view_for_class(klass, options = {})
+ style = options.delete(:style) || UITableViewCellStyleDefault
+ identifier = options.delete(:reuseIdentifier) || options.delete(:reuse_identifier)
+ klass.alloc.initWithStyle(style, reuseIdentifier: identifier)
+ end
+ end
+end
View
35 lib/builders/ui_view_builder.rb
@@ -0,0 +1,35 @@
+module UI
+ class UIViewBuilder
+ STRUCTS_MAP = {
+ CGAffineTransform => Proc.new {|v| NSValue.valueWithCGAffineTransform(v) },
+ CGPoint => Proc.new {|v| NSValue.valueWithCGPoint(v) },
+ CGRect => Proc.new {|v| NSValue.valueWithCGRect(v) },
+ CGSize => Proc.new {|v| NSValue.valueWithCGSize(v) },
+ UIEdgeInsets => Proc.new {|v| NSValue.valueWithUIEdgeInsets(v) },
+ UIOffset => Proc.new {|v| NSValue.valueWithUIOffset(v) }
+ }
+
+ attr_reader :view
+
+ def build(klass, options = {})
+ @view = view_for_class(klass, options)
+
+ unless options.nil?
+ options.each do |k,v|
+ options[k] = STRUCTS_MAP[v.class].call(v) if STRUCTS_MAP.has_key?(v.class)
+ end
+ self.setValuesForKeysWithDictionary(options)
+ end
+
+ @view
+ end
+
+ def view_for_class(klass, options = {})
+ klass.alloc.initWithFrame(CGRectZero)
+ end
+
+ def setValue(value, forUndefinedKey:key)
+ @view.setValue(value, forKey: key)
+ end
+ end
+end
View
16 lib/extensions/ui_color.rb
@@ -0,0 +1,16 @@
+class UIColor
+ # reference: http://color.rubyforge.org/
+ def self.from_html(html_colour)
+ html_colour = html_colour.gsub(%r{[#;]}, '')
+ case html_colour.size
+ when 3
+ colours = html_colour.scan(%r{[0-9A-Fa-f]}).map { |el| (el * 2).to_i(16) }
+ when 6
+ colours = html_colour.scan(%r<[0-9A-Fa-f]{2}>).map { |el| el.to_i(16) }
+ else
+ raise ArgumentError
+ end
+
+ UIColor.colorWithRed(colours[0]/255.0, green: colours[1]/255.0, blue: colours[2]/255.0, alpha: 1)
+ end
+end
View
93 lib/simple_view.rb
@@ -1,14 +1,5 @@
module UI
class Layout
- STRUCTS_MAP = {
- CGAffineTransform => Proc.new {|v| NSValue.valueWithCGAffineTransform(v) },
- CGPoint => Proc.new {|v| NSValue.valueWithCGPoint(v) },
- CGRect => Proc.new {|v| NSValue.valueWithCGRect(v) },
- CGSize => Proc.new {|v| NSValue.valueWithCGSize(v) },
- UIEdgeInsets => Proc.new {|v| NSValue.valueWithUIEdgeInsets(v) },
- UIOffset => Proc.new {|v| NSValue.valueWithUIOffset(v) }
- }
-
attr_accessor :view, :locals
def self.setup(view = nil, locals = {}, &block)
@@ -28,13 +19,6 @@ def initialize(view = nil, locals = {})
def add(klass, options = {}, &block)
subview = ViewBuilder.build(klass, options)
- unless options.nil?
- options.each do |k,v|
- options[k] = STRUCTS_MAP[v.class].call(v) if STRUCTS_MAP.has_key?(v.class)
- end
- subview.setValuesForKeysWithDictionary(options)
- end
-
if block_given?
child_layout = Layout.new(subview, @locals)
child_layout.instance_eval &block
@@ -70,15 +54,15 @@ def web_view(options = {}, &block) add(UIWebView, options, &block); e
class ViewBuilder
@@builders = {
- UIView => Proc.new {|klass, options| ViewBuilder.create_ui_view(klass, options) },
- UIControl => Proc.new {|klass, options| ViewBuilder.create_ui_control(klass, options) },
- UIActivityIndicatorView => Proc.new {|klass, options| ViewBuilder.create_ui_activity_indicator_view(klass, options) },
- UIButton => Proc.new {|klass, options| ViewBuilder.create_ui_button(klass, options) },
- UIImageView => Proc.new {|klass, options| ViewBuilder.create_ui_image_view(klass, options) },
- UIProgressView => Proc.new {|klass, options| ViewBuilder.create_ui_progress_view(klass, options) },
- UISegmentedControl => Proc.new {|klass, options| ViewBuilder.create_ui_segmented_control(klass, options) },
- UITableView => Proc.new {|klass, options| ViewBuilder.create_ui_table_view(klass, options) },
- UITableViewCell => Proc.new {|klass, options| ViewBuilder.create_ui_table_view_cell(klass, options) }
+ UIView => UIViewBuilder.new,
+ UIControl => UIControlBuilder.new,
+ UIActivityIndicatorView => UIActivityIndicatorViewBuilder.new,
+ UIButton => UIButtonBuilder.new,
+ UIImageView => UIImageViewBuilder.new,
+ UIProgressView => UIProgressViewBuilder.new,
+ UISegmentedControl => UISegmentedControlBuilder.new,
+ UITableView => UITableViewBuilder.new,
+ UITableViewCell => UITableViewCellBuilder.new
}
def self.build(klass, options = {})
@@ -89,63 +73,12 @@ def self.build(klass, options = {})
else
builder = @@builders[UIView]
end
- builder.call(klass, options)
- end
-
- def self.register(klass, proc)
- @@builders[klass] = proc
- end
-
- private
-
- def self.create_ui_view(klass, options = {})
- klass.alloc.initWithFrame(CGRectZero)
- end
-
- def self.create_ui_control(klass, options = {})
- klass.alloc.init
- end
-
- def self.create_ui_activity_indicator_view(klass, options = {})
- style = options.delete(:style) || UIActivityIndicatorViewStyleWhite
- UIActivityIndicatorView.alloc.initWithActivityIndicatorStyle(style)
- end
-
- def self.create_ui_button(klass, options = {})
- button_type = options.delete(:buttonType) || UIButtonTypeRoundedRect
- UIButton.buttonWithType(button_type)
- end
-
- def self.create_ui_image_view(klass, options = {})
- image = options.delete(:image)
- highlighted_image = options.delete(:highlightedImage)
- if image && highlighted_image
- UIImageView.alloc.initWithImage(image, highlightedImage:highlighted_image)
- elsif image
- UIImageView.alloc.initWithImage(image)
- else
- UIImageView.alloc.initWithFrame(CGRectZero)
- end
- end
-
- def self.create_ui_progress_view(klass, options = {})
- style = options.delete(:style) || UIProgressViewStyleDefault
- UIProgressView.alloc.initWithProgressViewStyle(style)
- end
-
- def self.create_ui_segmented_control(klass, options = {})
- items = options.delete(:items) || []
- UISegmentedControl.alloc.initWithItems(items)
- end
-
- def self.create_ui_table_view(klass, options = {})
- style = options.delete(:style) || UITableViewStylePlain
- UITableView.alloc.initWithFrame(CGRectZero, style: style)
+
+ builder.build(klass, options)
end
- def self.create_ui_table_view_cell(klass, options = {})
- style = options.delete(:style) || UITableViewCellStyleDefault
- UITableViewCell.alloc.initWithStyle(style, reuseIdentifier: options[:reuseIdentifier])
+ def self.register(klass, builder)
+ @@builders[klass] = builder
end
end
end
View
BIN resources/test.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
12 spec/builders/ui_activity_indicator_view_builder_spec.rb
@@ -0,0 +1,12 @@
+describe "UIActivityIndicatorViewBuilder" do
+ it "should build UIActivityIndicatorView" do
+ view = UI::UIActivityIndicatorViewBuilder.new.build(UIActivityIndicatorView)
+ view.class.should == UIActivityIndicatorView
+ view.activityIndicatorViewStyle.should == UIActivityIndicatorViewStyleWhite
+ end
+
+ it "should build UIActivityIndicatorView with style" do
+ view = UI::UIActivityIndicatorViewBuilder.new.build(UIActivityIndicatorView, style: UIActivityIndicatorViewStyleGray)
+ view.activityIndicatorViewStyle.should == UIActivityIndicatorViewStyleGray
+ end
+end
View
12 spec/builders/ui_button_builder_spec.rb
@@ -0,0 +1,12 @@
+describe "UIButtonBuilder" do
+ it "should build UIButton" do
+ button = UI::UIButtonBuilder.new.build(UIButton)
+ button.class.should == UIRoundedRectButton
+ button.buttonType.should == UIButtonTypeRoundedRect
+ end
+
+ it "should build UIButton with buttonType" do
+ button = UI::UIButtonBuilder.new.build(UIButton, buttonType: UIButtonTypeDetailDisclosure)
+ button.buttonType.should == UIButtonTypeDetailDisclosure
+ end
+end
View
5 spec/builders/ui_control_builder_spec.rb
@@ -0,0 +1,5 @@
+describe "UIControlBuilder" do
+ it "should build UIControl" do
+ UI::UIControlBuilder.new.build(UIControl).class.should == UIControl
+ end
+end
View
31 spec/builders/ui_image_view_builder_spec.rb
@@ -0,0 +1,31 @@
+describe "UIImageViewBuilder" do
+ it "should build UIImageView" do
+ image_view = UI::UIImageViewBuilder.new.build(UIImageView)
+ image_view.class.should == UIImageView
+ end
+
+ it "should build UIImageView with image" do
+ image = UIImage.imageNamed "test.jpg"
+ image_view = UI::UIImageViewBuilder.new.build(UIImageView, image: image)
+ image_view.image.should == image
+ end
+
+ it "should build UIImageView with image string" do
+ image_view = UI::UIImageViewBuilder.new.build(UIImageView, image: "test.jpg")
+ image_view.image.class.should == UIImage
+ end
+
+ it "should build UIImageView with image and highlightedImage" do
+ image = UIImage.imageNamed "test.jpg"
+ highlighted = UIImage.imageNamed "test.jpg"
+ image_view = UI::UIImageViewBuilder.new.build(UIImageView, image: image, highlightedImage: highlighted)
+ image_view.image.should == image
+ image_view.highlightedImage.should == highlighted
+ end
+
+ it "should build UIImageView with image string and highlightedImage string" do
+ image_view = UI::UIImageViewBuilder.new.build(UIImageView, image: "test.jpg", highlightedImage: "test.jpg")
+ image_view.image.class.should == UIImage
+ image_view.highlightedImage.class.should == UIImage
+ end
+end
View
12 spec/builders/ui_progress_view_builder_spec.rb
@@ -0,0 +1,12 @@
+describe "UIProgressViewBuilder" do
+ it "should build UIProgressView" do
+ view = UI::UIProgressViewBuilder.new.build(UIProgressView)
+ view.class.should == UIProgressView
+ view.progressViewStyle.should == UIProgressViewStyleDefault
+ end
+
+ it "should build UIProgressView with style" do
+ view = UI::UIProgressViewBuilder.new.build(UIProgressView, style: UIProgressViewStyleBar)
+ view.progressViewStyle.should == UIProgressViewStyleBar
+ end
+end
View
13 spec/builders/ui_segmented_control_builder_spec.rb
@@ -0,0 +1,13 @@
+describe "UISegmentedControlBuilder" do
+ it "should build UISegmentedControl" do
+ view = UI::UISegmentedControlBuilder.new.build(UISegmentedControl)
+ view.class.should == UISegmentedControl
+ view.numberOfSegments.should == 0
+ end
+
+ it "should build UISegmentedControl with items" do
+ items = ["ABC"]
+ view = UI::UISegmentedControlBuilder.new.build(UISegmentedControl, items: items)
+ view.numberOfSegments.should == 1
+ end
+end
View
12 spec/builders/ui_table_view_builder_spec.rb
@@ -0,0 +1,12 @@
+describe "UITableViewBuilder" do
+ it "should build UITableView" do
+ view = UI::UITableViewBuilder.new.build(UITableView)
+ view.class.should == UITableView
+ view.style.should == UITableViewStylePlain
+ end
+
+ it "should build UITableView with style" do
+ view = UI::UITableViewBuilder.new.build(UITableView, style: UITableViewStyleGrouped)
+ view.style.should == UITableViewStyleGrouped
+ end
+end
View
17 spec/builders/ui_table_view_cell_builder_spec.rb
@@ -0,0 +1,17 @@
+describe "UITableViewCellBuilder" do
+ it "should build UITableViewCell" do
+ view = UI::UITableViewCellBuilder.new.build(UITableViewCell)
+ view.class.should == UITableViewCell
+ view.style.should == UITableViewCellStyleDefault
+ end
+
+ it "should build UITableViewCell with style" do
+ view = UI::UITableViewCellBuilder.new.build(UITableViewCell, style: UITableViewCellStyleSubtitle)
+ view.style.should == UITableViewCellStyleSubtitle
+ end
+
+ it "should build UITableViewCell with style and reuseIdentifier" do
+ view = UI::UITableViewCellBuilder.new.build(UITableViewCell, reuseIdentifier: "CellIdentifier")
+ view.reuseIdentifier.should == "CellIdentifier"
+ end
+end
View
5 spec/builders/ui_view_builder_spec.rb
@@ -0,0 +1,5 @@
+describe "UIViewBuilder" do
+ it "should build UIView" do
+ UI::UIViewBuilder.new.build(UIView).class.should == UIView
+ end
+end
View
16 spec/extensions/ui_color_spec.rb
@@ -0,0 +1,16 @@
+describe "UIColor" do
+ describe "#from_html" do
+ it "should convert HTML hex color to UIColor" do
+ color = UIColor.from_html("#f00")
+ r = Pointer.new(:float)
+ g = Pointer.new(:float)
+ b = Pointer.new(:float)
+ a = Pointer.new(:float)
+ color.getRed(r, green: g, blue: b, alpha: a)
+ r[0].should == 1
+ g[0].should == 0
+ b[0].should == 0
+ a[0].should == 1
+ end
+ end
+end
View
115 spec/simple_view_spec.rb
@@ -135,119 +135,4 @@
end
end
end
-
- describe "ViewBuilder" do
- it "should build UIView" do
- UI::ViewBuilder.build(UIView).class.should == UIView
- end
-
- it "should build UIControl" do
- UI::ViewBuilder.build(UIControl).class.should == UIControl
- end
-
- describe "UIActivityIndicatorView" do
- it "should build UIActivityIndicatorView" do
- view = UI::ViewBuilder.build(UIActivityIndicatorView)
- view.class.should == UIActivityIndicatorView
- view.activityIndicatorViewStyle.should == UIActivityIndicatorViewStyleWhite
- end
-
- it "should build UIActivityIndicatorView with style" do
- view = UI::ViewBuilder.build(UIActivityIndicatorView, style: UIActivityIndicatorViewStyleGray)
- view.activityIndicatorViewStyle.should == UIActivityIndicatorViewStyleGray
- end
- end
-
- describe "UIButton" do
- it "should build UIButton" do
- button = UI::ViewBuilder.build(UIButton)
- button.class.should == UIRoundedRectButton
- button.buttonType.should == UIButtonTypeRoundedRect
- end
-
- it "should build UIButton with buttonType" do
- button = UI::ViewBuilder.build(UIButton, buttonType: UIButtonTypeDetailDisclosure)
- button.buttonType.should == UIButtonTypeDetailDisclosure
- end
- end
-
- describe "UIImageView" do
- it "should build UIImageView" do
- image_view = UI::ViewBuilder.build(UIImageView)
- image_view.class.should == UIImageView
- end
-
- it "should build UIImageView with image" do
- image = UIImage.imageNamed "cat"
- image_view = UI::ViewBuilder.build(UIImageView, image: image)
- image_view.image.should == image
- end
-
- it "should build UIImageView with image and highlightedImage" do
- image = UIImage.imageNamed "cat"
- highlighted = UIImage.imageNamed "nyan"
- image_view = UI::ViewBuilder.build(UIImageView, image: image, highlightedImage: highlighted)
- image_view.image.should == image
- image_view.highlightedImage.should == highlighted
- end
- end
-
- describe "UIProgressView" do
- it "should build UIProgressView" do
- view = UI::ViewBuilder.build(UIProgressView)
- view.class.should == UIProgressView
- view.progressViewStyle.should == UIProgressViewStyleDefault
- end
-
- it "should build UIProgressView with style" do
- view = UI::ViewBuilder.build(UIProgressView, style: UIProgressViewStyleBar)
- view.progressViewStyle.should == UIProgressViewStyleBar
- end
- end
-
- describe "UISegmentedControl" do
- it "should build UISegmentedControl" do
- view = UI::ViewBuilder.build(UISegmentedControl)
- view.class.should == UISegmentedControl
- view.numberOfSegments.should == 0
- end
-
- it "should build UISegmentedControl with items" do
- items = ["ABC"]
- view = UI::ViewBuilder.build(UISegmentedControl, items: items)
- view.numberOfSegments.should == 1
- end
- end
-
- describe "UITableView" do
- it "should build UITableView" do
- view = UI::ViewBuilder.build(UITableView)
- view.class.should == UITableView
- view.style.should == UITableViewStylePlain
- end
-
- it "should build UITableView with style" do
- view = UI::ViewBuilder.build(UITableView, style: UITableViewStyleGrouped)
- view.style.should == UITableViewStyleGrouped
- end
- end
-
- describe "UITableViewCell" do
- it "should build UITableViewCell" do
- view = UI::ViewBuilder.build(UITableViewCell)
- view.class.should == UITableViewCell
- view.style.should == UITableViewCellStyleDefault
- end
-
- it "should build UITableViewCell with style" do
- view = UI::ViewBuilder.build(UITableViewCell, style: UITableViewCellStyleSubtitle)
- view.style.should == UITableViewCellStyleSubtitle
- end
-
- it "should build UITableViewCell with style" do
- view = UI::ViewBuilder.build(UITableViewCell, reuseIdentifier: "CellIdentifier")
- view.reuseIdentifier.should == "CellIdentifier"
- end
- end
- end
end

0 comments on commit 155c147

Please sign in to comment.
Something went wrong with that request. Please try again.