From b0e43580238428d713fe2c9d138ce9c7a8d0d405 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 09:44:01 -0400 Subject: [PATCH 01/25] Add "Working on Features" section to readme So that people don't have the same questions I did. --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 0aa3c42..1ebed4a 100644 --- a/README.md +++ b/README.md @@ -777,6 +777,15 @@ Opening a ticket is usually the best and we respond to those pretty quickly. I'm very open to ideas. Tweet me with your ideas or open a ticket (I don't mind!) and let's discuss. +## Working on Features + +1. Clone the repos into `Your-Project/Vendor/ProMotion` +2. Update your `Gemfile`to reference the project as `gem 'ProMotion', :path => "vendor/ProMotion/"` +3. If you're also using [BubbleWrap](http://www.bubblewrap.io), add this line to your `Rakefile`: `app.detect_dependencies = false` +4. Run `bundle` +5. Run `rake clean` and then `rake` +6. Contribute! + ## Submitting a Pull Request 1. Fork the project From fdb3945a76075215648a786b746a99f38f2fe510 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 10:10:12 -0400 Subject: [PATCH 02/25] Clean up trailing spaces globally. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I know it's not a big thing, but my editor highlights them in bright purple and auto-trims them on save… so i thought i'd clean them up :) --- .../cocoatouch/SplitViewController.rb | 2 +- .../cocoatouch/TableViewController.rb | 10 +++---- lib/ProMotion/cocoatouch/ViewController.rb | 10 +++---- lib/ProMotion/delegate.rb | 6 ++-- lib/ProMotion/helpers/console.rb | 6 ++-- .../_tables/_searchable_table.rb | 4 +-- .../_tables/_sectioned_table.rb | 20 ++++++------- .../screen_helpers/_tables/grouped_table.rb | 2 +- .../screen_helpers/screen_elements.rb | 4 +-- .../screen_helpers/screen_navigation.rb | 14 +++++----- lib/ProMotion/screen_helpers/screen_tabs.rb | 22 +++++++-------- lib/ProMotion/screen_helpers/split_screen.rb | 16 +++++------ lib/ProMotion/screens/_screen_module.rb | 8 +++--- lib/ProMotion/screens/_table_screen_module.rb | 2 +- spec/ios_version_spec.rb | 2 +- spec/main_spec.rb | 2 +- spec/split_screen_in_tab_bar_spec.rb | 28 +++++++++---------- spec/split_screen_open_screen_spec.rb | 18 ++++++------ spec/split_screen_spec.rb | 16 +++++------ spec/view_helper_spec.rb | 14 +++++----- 20 files changed, 103 insertions(+), 103 deletions(-) diff --git a/lib/ProMotion/cocoatouch/SplitViewController.rb b/lib/ProMotion/cocoatouch/SplitViewController.rb index 664984a..695736b 100644 --- a/lib/ProMotion/cocoatouch/SplitViewController.rb +++ b/lib/ProMotion/cocoatouch/SplitViewController.rb @@ -14,7 +14,7 @@ class SplitViewController < UISplitViewController # set the button from the old detail screen to the new one button = detail_screen.navigationItem.leftBarButtonItem s.navigationItem.leftBarButtonItem = button - + self.viewControllers = [self.viewControllers.first, s.main_controller] end def screens=(s_array) diff --git a/lib/ProMotion/cocoatouch/TableViewController.rb b/lib/ProMotion/cocoatouch/TableViewController.rb index d30b40c..b517c3f 100644 --- a/lib/ProMotion/cocoatouch/TableViewController.rb +++ b/lib/ProMotion/cocoatouch/TableViewController.rb @@ -20,15 +20,15 @@ module ProMotion super self.view_did_appear(animated) if self.respond_to?("view_did_appear:") end - + def viewWillDisappear(animated) self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:") - super + super end - + def viewDidDisappear(animated) self.view_did_disappear(animated) if self.respond_to?("view_did_disappear:") - super + super end def shouldAutorotateToInterfaceOrientation(orientation) @@ -42,7 +42,7 @@ module ProMotion def willRotateToInterfaceOrientation(orientation, duration:duration) self.will_rotate(orientation, duration) end - + def didRotateFromInterfaceOrientation(orientation) self.on_rotate end diff --git a/lib/ProMotion/cocoatouch/ViewController.rb b/lib/ProMotion/cocoatouch/ViewController.rb index 0a9b4eb..cf41b3d 100644 --- a/lib/ProMotion/cocoatouch/ViewController.rb +++ b/lib/ProMotion/cocoatouch/ViewController.rb @@ -20,17 +20,17 @@ module ProMotion super self.view_did_appear(animated) if self.respond_to?("view_did_appear:") end - + def viewWillDisappear(animated) self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:") - super + super end - + def viewDidDisappear(animated) if self.respond_to?("view_did_disappear:") self.view_did_disappear(animated) end - super + super end def shouldAutorotateToInterfaceOrientation(orientation) @@ -44,7 +44,7 @@ module ProMotion def willRotateToInterfaceOrientation(orientation, duration:duration) self.will_rotate(orientation, duration) end - + def didRotateFromInterfaceOrientation(orientation) self.on_rotate end diff --git a/lib/ProMotion/delegate.rb b/lib/ProMotion/delegate.rb index b7b3c79..919db5f 100644 --- a/lib/ProMotion/delegate.rb +++ b/lib/ProMotion/delegate.rb @@ -3,7 +3,7 @@ module ProMotion include ProMotion::ScreenTabs include ProMotion::SplitScreen if NSBundle.mainBundle.infoDictionary["UIDeviceFamily"].include?("2") attr_accessor :window - + def application(application, didFinishLaunchingWithOptions:launch_options) return true if RUBYMOTION_ENV == "test" @@ -15,7 +15,7 @@ module ProMotion true end - + def app_delegate UIApplication.sharedApplication.delegate end @@ -50,7 +50,7 @@ module ProMotion get_home_screen.send(:on_load) if get_home_screen.respond_to?(:on_load) load_root_screen get_home_screen end - + def get_home_screen @home_screen end diff --git a/lib/ProMotion/helpers/console.rb b/lib/ProMotion/helpers/console.rb index 3c38a34..2446575 100644 --- a/lib/ProMotion/helpers/console.rb +++ b/lib/ProMotion/helpers/console.rb @@ -3,15 +3,15 @@ module ProMotion NAME = "RubyMotion::Console: " DEFAULT_COLOR = [ '', '' ] RED_COLOR = [ "\e[0;31m", "\e[0m" ] # Must be in double quotes - GREEN_COLOR = [ "\e[0;32m", "\e[0m" ] - PURPLE_COLOR = [ "\e[0;35m", "\e[0m" ] + GREEN_COLOR = [ "\e[0;32m", "\e[0m" ] + PURPLE_COLOR = [ "\e[0;35m", "\e[0m" ] class << self def log(log, with_color:color) return if RUBYMOTION_ENV == "test" puts color[0] + NAME + log + color[1] end - + def log(log, withColor:color) return if RUBYMOTION_ENV == "test" warn "[DEPRECATION] `log(log, withColor:color)` is deprecated. Use `log(log, with_color:color)`" diff --git a/lib/ProMotion/screen_helpers/_tables/_searchable_table.rb b/lib/ProMotion/screen_helpers/_tables/_searchable_table.rb index d475fac..03e1e1a 100644 --- a/lib/ProMotion/screen_helpers/_tables/_searchable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_searchable_table.rb @@ -22,13 +22,13 @@ module ProMotion::MotionTable @contacts_search_display_controller.delegate = params[:delegate] @contacts_search_display_controller.searchResultsDataSource = params[:data_source] @contacts_search_display_controller.searchResultsDelegate = params[:search_results_delegate] - + self.table_view.tableHeaderView = search_bar end alias :makeSearchable :make_searchable ######### iOS methods, headless camel case ####### - + def searchDisplayController(controller, shouldReloadTableForSearchString:search_string) @mt_filtered_data = nil @mt_filtered_data = [] diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index edc1dd2..f514a61 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -55,7 +55,7 @@ module ProMotion::MotionTable ProMotion::Console.log("Action not implemented: #{action.to_s}", with_color: ProMotion::Console::RED_COLOR) end end - + def set_cell_attributes(element, args = {}) args.each do |k, v| if v.is_a? Hash @@ -78,7 +78,7 @@ module ProMotion::MotionTable data_cell[:arguments] = {} unless data_cell[:arguments] data_cell[:arguments][:value] = switch.isOn if data_cell[:arguments].is_a? Hash data_cell[:accessory_action] ||= data_cell[:accessoryAction] # For legacy support - + trigger_action(data_cell[:accessory_action], data_cell[:arguments]) if data_cell[:accessory_action] end @@ -105,14 +105,14 @@ module ProMotion::MotionTable # Set table_data_index if you want the right hand index column (jumplist) def sectionIndexTitlesForTableView(table_view) if self.respond_to?(:table_data_index) - self.table_data_index + self.table_data_index end end - + def remap_data_cell(data_cell) # Re-maps legacy data cell calls - mappings = { - cell_style: :cellStyle, + mappings = { + cell_style: :cellStyle, cell_identifier: :cellIdentifier, cell_class: :cellClass, masks_to_bounds: :masksToBounds, @@ -143,9 +143,9 @@ module ProMotion::MotionTable data_cell = cell_at_section_and_index(indexPath.section, indexPath.row) return UITableViewCell.alloc.init unless data_cell - + data_cell = self.remap_data_cell(data_cell) - + data_cell[:cell_style] ||= UITableViewCellStyleDefault data_cell[:cell_identifier] ||= "Cell" cell_identifier = data_cell[:cell_identifier] @@ -154,7 +154,7 @@ module ProMotion::MotionTable table_cell = table_view.dequeueReusableCellWithIdentifier(cell_identifier) unless table_cell table_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:cell_identifier) - + # Add optimizations here table_cell.layer.masksToBounds = true if data_cell[:masks_to_bounds] table_cell.backgroundColor = data_cell[:background_color] if data_cell[:background_color] @@ -165,7 +165,7 @@ module ProMotion::MotionTable if data_cell[:cell_class_attributes] set_cell_attributes table_cell, data_cell[:cell_class_attributes] end - + if data_cell[:accessory_view] table_cell.accessoryView = data_cell[:accessory_view] table_cell.accessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth diff --git a/lib/ProMotion/screen_helpers/_tables/grouped_table.rb b/lib/ProMotion/screen_helpers/_tables/grouped_table.rb index 366244a..07e877f 100644 --- a/lib/ProMotion/screen_helpers/_tables/grouped_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/grouped_table.rb @@ -1,7 +1,7 @@ module ProMotion::MotionTable module GroupedTable include SectionedTable - + def table_view @table_view ||= UITableView.alloc.initWithFrame(self.view.frame, style:UITableViewStyleGrouped) @table_view.dataSource = self; diff --git a/lib/ProMotion/screen_helpers/screen_elements.rb b/lib/ProMotion/screen_helpers/screen_elements.rb index 3ee3ce2..019cb67 100644 --- a/lib/ProMotion/screen_helpers/screen_elements.rb +++ b/lib/ProMotion/screen_helpers/screen_elements.rb @@ -1,7 +1,7 @@ module ProMotion module ScreenElements include ProMotion::ViewHelper - + def add(v, attrs = {}) if attrs && attrs.length > 0 set_attributes(v, attrs) @@ -22,7 +22,7 @@ module ProMotion def bounds return self.view.bounds end - + def frame return self.view.frame end diff --git a/lib/ProMotion/screen_helpers/screen_navigation.rb b/lib/ProMotion/screen_helpers/screen_navigation.rb index f5e0cae..2b6f509 100644 --- a/lib/ProMotion/screen_helpers/screen_navigation.rb +++ b/lib/ProMotion/screen_helpers/screen_navigation.rb @@ -2,20 +2,20 @@ module ProMotion module ScreenNavigation def open_screen(screen, args = {}) - + # Apply properties to instance screen = setup_screen_for_open(screen, args) ensure_wrapper_controller_in_place(screen, args) - screen.send(:on_load) if screen.respond_to?(:on_load) + screen.send(:on_load) if screen.respond_to?(:on_load) animated = args[:animated] || true return self.split_screen.detail_screen = screen if args[:in_detail] && self.split_screen return self.split_screen.master_screen = screen if args[:in_master] && self.split_screen - + if args[:close_all] open_root_screen screen - + elsif args[:modal] present_modal_view_controller screen, animated @@ -44,7 +44,7 @@ module ProMotion def app_delegate UIApplication.sharedApplication.delegate end - + def close_screen(args = {}) args ||= {} args[:animated] ||= true @@ -58,7 +58,7 @@ module ProMotion else Console.log("Tried to close #{self.to_s}; however, this screen isn't modal or in a nav bar.", withColor: Console::PURPLE_COLOR) - + end end alias :close :close_screen @@ -95,7 +95,7 @@ module ProMotion screen.parent_screen = self if screen.respond_to?("parent_screen=") screen.title = args[:title] if args[:title] && screen.respond_to?("title=") screen.modal = args[:modal] if args[:modal] && screen.respond_to?("modal=") - + # Hide bottom bar? screen.hidesBottomBarWhenPushed = args[:hide_tab_bar] == true diff --git a/lib/ProMotion/screen_helpers/screen_tabs.rb b/lib/ProMotion/screen_helpers/screen_tabs.rb index 49e7503..f933d7d 100644 --- a/lib/ProMotion/screen_helpers/screen_tabs.rb +++ b/lib/ProMotion/screen_helpers/screen_tabs.rb @@ -10,33 +10,33 @@ module ProMotion screens.each do |s| s = s.new if s.respond_to?(:new) - + s.tabBarItem.tag = tag_index - + s.parent_screen = self if self.is_a?(UIViewController) && s.respond_to?("parent_screen=") s.tab_bar = tab_bar_controller if s.respond_to?("tab_bar=") - + vc = s.respond_to?(:main_controller) ? s.main_controller : s view_controllers << vc - + tag_index += 1 - + s.on_load if s.respond_to?(:on_load) end tab_bar_controller.viewControllers = view_controllers tab_bar_controller end - + # Open a UITabBarController with the specified screens as the # root view controller of the current app. # @param [Array] A comma-delimited list of screen classes or instances. # @return [UITabBarController] def open_tab_bar(*screens) tab_bar = tab_bar_controller(*screens) - + a = self.respond_to?(:load_root_screen) ? self : UIApplication.sharedApplication.delegate - + a.load_root_screen(tab_bar) tab_bar end @@ -66,12 +66,12 @@ module ProMotion title = tab[:title] if tab[:title] tab[:tag] ||= @current_tag ||= 0 @current_tag = tab[:tag] + 1 - + tab_bar_item = create_tab_bar_icon(tab[:system_icon], tab[:tag]) if tab[:system_icon] tab_bar_item = create_tab_bar_icon_custom(title, tab[:icon], tab[:tag]) if tab[:icon] - + tab_bar_item.badgeValue = tab[:badge_number].to_s unless tab[:badge_number].nil? || tab[:badge_number] <= 0 - + return tab_bar_item end diff --git a/lib/ProMotion/screen_helpers/split_screen.rb b/lib/ProMotion/screen_helpers/split_screen.rb index 2b4ecb4..728dc6d 100644 --- a/lib/ProMotion/screen_helpers/split_screen.rb +++ b/lib/ProMotion/screen_helpers/split_screen.rb @@ -3,20 +3,20 @@ module ProMotion def split_screen_controller(master, detail) master_main = master.navigationController ? master.navigationController : master detail_main = detail.navigationController ? detail.navigationController : detail - + split = SplitViewController.alloc.init split.viewControllers = [ master_main, detail_main ] split.delegate = self - + split end - + def create_split_screen(master, detail, args={}) master = master.new if master.respond_to?(:new) detail = detail.new if detail.respond_to?(:new) - + split = split_screen_controller(master, detail) - + [master, detail].each do |s| s.split_screen = split if s.respond_to?("split_screen=") s.on_load if s.respond_to?(:on_load) @@ -24,15 +24,15 @@ module ProMotion split end - + def open_split_screen(master, detail, args={}) split = create_split_screen(master, detail, args) open split, args split end - + # UISplitViewControllerDelegate methods - + def splitViewController(svc, willHideViewController: vc, withBarButtonItem: button, forPopoverController: pc) button.title = vc.title svc.detail_screen.navigationItem.leftBarButtonItem = button; diff --git a/lib/ProMotion/screens/_screen_module.rb b/lib/ProMotion/screens/_screen_module.rb index ab4bb72..5dc18c2 100644 --- a/lib/ProMotion/screens/_screen_module.rb +++ b/lib/ProMotion/screens/_screen_module.rb @@ -12,13 +12,13 @@ module ProMotion unless self.is_a?(UIViewController) raise StandardError.new("ERROR: Screens must extend UIViewController or a subclass of UIViewController.") end - + args.each do |k, v| self.send("#{k}=", v) if self.respond_to?("#{k}=") end self.add_nav_bar if args[:nav_bar] - self.table_setup if self.respond_to?(:table_setup) + self.table_setup if self.respond_to?(:table_setup) self.on_init if self.respond_to?(:on_init) self end @@ -186,7 +186,7 @@ module ProMotion end orientations end - + def supported_device_families NSBundle.mainBundle.infoDictionary["UIDeviceFamily"].map do |m| case m @@ -197,7 +197,7 @@ module ProMotion end end end - + def supported_device_family?(family) supported_device_families.include?(family) end diff --git a/lib/ProMotion/screens/_table_screen_module.rb b/lib/ProMotion/screens/_table_screen_module.rb index d7c81cf..925fb56 100644 --- a/lib/ProMotion/screens/_table_screen_module.rb +++ b/lib/ProMotion/screens/_table_screen_module.rb @@ -3,7 +3,7 @@ module ProMotion include MotionTable::PlainTable include MotionTable::SearchableTable include ProMotion::ScreenModule - + def update_table_data self.update_table_view_data(table_data) end diff --git a/spec/ios_version_spec.rb b/spec/ios_version_spec.rb index 7138d8a..3e2884a 100644 --- a/spec/ios_version_spec.rb +++ b/spec/ios_version_spec.rb @@ -24,5 +24,5 @@ describe "ios version" do it "#ios_version_less_eq?" do @dummy.ios_version_less_eq?(@dummy.ios_version).should == true end - + end diff --git a/spec/main_spec.rb b/spec/main_spec.rb index af373d0..52ded92 100644 --- a/spec/main_spec.rb +++ b/spec/main_spec.rb @@ -3,7 +3,7 @@ describe "pro motion module" do it "should have 'PM' module" do should.not.raise(NameError) { PM } end - + it "should not allow screen inclusion into just any class" do dummy = DummyClass.new dummy.extend ProMotion::ScreenModule diff --git a/spec/split_screen_in_tab_bar_spec.rb b/spec/split_screen_in_tab_bar_spec.rb index be81229..2661351 100644 --- a/spec/split_screen_in_tab_bar_spec.rb +++ b/spec/split_screen_in_tab_bar_spec.rb @@ -2,48 +2,48 @@ describe "split screen in tab bar functionality" do before do @app = TestDelegate.new - + @master_screen = HomeScreen.new nav_bar: true @detail_screen = BasicScreen.new nav_bar: true - + @split_screen = @app.create_split_screen @master_screen, @detail_screen @tab = @app.open_tab_bar @split_screen, HomeScreen, BasicScreen end - + it "should create a UISplitViewController" do @split_screen.is_a?(UISplitViewController).should == true end - + it "should have two viewControllers" do @split_screen.viewControllers.length.should == 2 end - + it "should set the root view to the tab bar" do @app.window.rootViewController.should == @tab end - - it "should return screens for the master_screen and detail_screen methods" do + + it "should return screens for the master_screen and detail_screen methods" do @split_screen.master_screen.is_a?(PM::Screen).should == true @split_screen.detail_screen.is_a?(PM::Screen).should == true end - - it "should return navigationControllers" do + + it "should return navigationControllers" do @split_screen.viewControllers.first.is_a?(UINavigationController).should == true @split_screen.viewControllers.last.is_a?(UINavigationController).should == true end - + it "should set the first viewController to HomeScreen's main controller" do @split_screen.master_screen.should == @master_screen @split_screen.viewControllers.first.should == @master_screen.main_controller end - + it "should set the second viewController to BasicScreen's main controller" do @split_screen.detail_screen.should == @detail_screen @split_screen.viewControllers.last.should == @detail_screen.main_controller end - - it "should set the tab bar first viewController to the split screen" do + + it "should set the tab bar first viewController to the split screen" do @tab.viewControllers.first.should == @split_screen end - + end \ No newline at end of file diff --git a/spec/split_screen_open_screen_spec.rb b/spec/split_screen_open_screen_spec.rb index 325a72e..0f6ecf1 100644 --- a/spec/split_screen_open_screen_spec.rb +++ b/spec/split_screen_open_screen_spec.rb @@ -2,45 +2,45 @@ describe "split screen `open` functionality" do before do @app = TestDelegate.new - + @master_screen = HomeScreen.new nav_bar: true @detail_screen_1 = BasicScreen.new # no nav_bar on this one @detail_screen_2 = BasicScreen.new(nav_bar: true) - + @split_screen = @app.open_split_screen @master_screen, @detail_screen_1 end - + it "should open a new screen in the detail view" do @master_screen.open @detail_screen_2, in_detail: true @split_screen.detail_screen.should == @detail_screen_2 @split_screen.viewControllers.first.should == @master_screen.main_controller @split_screen.viewControllers.last.should == @detail_screen_2.main_controller end - + it "should open a new screen in the master view" do @detail_screen_1.open @detail_screen_2, in_master: true @split_screen.master_screen.should == @detail_screen_2 @split_screen.viewControllers.first.should == @detail_screen_2.main_controller @split_screen.viewControllers.last.should == @detail_screen_1.main_controller end - + it "should open a new screen in the master view's navigation controller" do @master_screen.open @detail_screen_2 @split_screen.detail_screen.should == @detail_screen_1 # no change @master_screen.navigationController.topViewController.should == @detail_screen_2 end - + it "should open a new modal screen in the detail view" do @detail_screen_1.open @detail_screen_2, modal: true @split_screen.detail_screen.should == @detail_screen_1 @detail_screen_1.presentedViewController.should == @detail_screen_2.main_controller end - - it "should not interfere with normal non-split screen navigation" do + + it "should not interfere with normal non-split screen navigation" do home = HomeScreen.new(nav_bar: true) child = BasicScreen.new home.open child, in_detail: true, in_master: true home.navigation_controller.topViewController.should == child end - + end \ No newline at end of file diff --git a/spec/split_screen_spec.rb b/spec/split_screen_spec.rb index 8aa6288..2fd506a 100644 --- a/spec/split_screen_spec.rb +++ b/spec/split_screen_spec.rb @@ -2,34 +2,34 @@ describe "split screen functionality" do before do @app = TestDelegate.new - + @master_screen = HomeScreen.new nav_bar: true @detail_screen = BasicScreen.new # no nav_bar on this one - + @split_screen = @app.open_split_screen @master_screen, @detail_screen end - + it "should have created a split screen" do @split_screen.should != nil @split_screen.is_a?(UISplitViewController).should == true end - + it "should have two viewControllers" do @split_screen.viewControllers.length.should == 2 end - + it "should set the root view to the UISplitScreenViewController" do @app.window.rootViewController.should == @split_screen end - + it "should set the first viewController to HomeScreen" do @split_screen.master_screen.should == @master_screen @split_screen.viewControllers.first.should == @master_screen.main_controller end - + it "should set the second viewController to BasicScreen" do @split_screen.detail_screen.should == @detail_screen @split_screen.viewControllers.last.should == @detail_screen.main_controller end - + end \ No newline at end of file diff --git a/spec/view_helper_spec.rb b/spec/view_helper_spec.rb index 92c1d74..f243e7b 100644 --- a/spec/view_helper_spec.rb +++ b/spec/view_helper_spec.rb @@ -3,7 +3,7 @@ describe "view helpers" do def equal_rect(rect) ->(obj) { CGRectEqualToRect obj, rect } end - + before do @dummy = UIView.alloc.initWithFrame CGRectZero @dummy.extend ProMotion::ViewHelper @@ -14,7 +14,7 @@ describe "view helpers" do end it "#frame_from_array should return a valid CGRect" do - @dummy.frame_from_array([0,0,320,480]).should equal_rect(CGRectMake(0,0,320,480)) + @dummy.frame_from_array([0,0,320,480]).should equal_rect(CGRectMake(0,0,320,480)) end it "should allow you to set attributes" do @@ -24,16 +24,16 @@ describe "view helpers" do it "should allow you to set nested attributes" do layered_view = UIView.alloc.initWithFrame(CGRectMake(0, 0, 10, 10)) - + @dummy.set_attributes layered_view, { layer: { backgroundColor: UIColor.redColor.CGColor } } - + layered_view.layer.backgroundColor.should == UIColor.redColor.CGColor end - + it "should allow you to set multiple nested attributes" do mask_layer = CAShapeLayer.layer layered_view = UIView.alloc.initWithFrame(CGRectMake(0, 0, 10, 10)) @@ -45,10 +45,10 @@ describe "view helpers" do } } } - + layered_view.layer.mask.backgroundColor.should == UIColor.redColor.CGColor end - + describe "content height" do before do From 98c01f08186b7f1d93263b0958122077cb3c3ece Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 12:15:36 -0400 Subject: [PATCH 03/25] Add note about detect_dependencies being a rubymotion bug. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ebed4a..bc90486 100644 --- a/README.md +++ b/README.md @@ -781,7 +781,7 @@ and let's discuss. 1. Clone the repos into `Your-Project/Vendor/ProMotion` 2. Update your `Gemfile`to reference the project as `gem 'ProMotion', :path => "vendor/ProMotion/"` -3. If you're also using [BubbleWrap](http://www.bubblewrap.io), add this line to your `Rakefile`: `app.detect_dependencies = false` +3. If you're also using [BubbleWrap](http://www.bubblewrap.io), add this line to your `Rakefile`: `app.detect_dependencies = false` *(This is a RubyMotion bug that should be resolved soon)* 4. Run `bundle` 5. Run `rake clean` and then `rake` 6. Contribute! From c8c0c43c49234aed8cb60e6ea68b31f85d738b83 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 12:56:56 -0400 Subject: [PATCH 04/25] Initial pass at a refreshable table. --- .../_tables/_refreshable_table.rb | 57 +++++++++++++++++++ .../_tables/_sectioned_table.rb | 3 + .../screen_helpers/_tables/grouped_table.rb | 1 + .../screen_helpers/_tables/plain_table.rb | 1 + lib/ProMotion/screens/_table_screen_module.rb | 13 +++++ 5 files changed, 75 insertions(+) create mode 100644 lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb new file mode 100644 index 0000000..bb29a86 --- /dev/null +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -0,0 +1,57 @@ +module ProMotion::MotionTable + module RefreshableTable + def make_refreshable + @refresh = UIRefreshControl.alloc.init + @refresh.attributedTitle = NSAttributedString.alloc.initWithString("Pull to Refresh") + @refresh.addTarget(self, action:'refreshView:', forControlEvents:UIControlEventValueChanged) + self.refreshControl = @refresh + # @on_refresh = get_refreshable_block + + + # params[:content_controller] ||= params[:contentController] + # params[:data_source] ||= params[:searchResultsDataSource] + # params[:search_results_delegate] ||= params[:searchResultsDelegate] + + # params[:frame] ||= CGRectMake(0, 0, 320, 44) # TODO: Don't hardcode this... + # params[:content_controller] ||= self + # params[:delegate] ||= self + # params[:data_source] ||= self + # params[:search_results_delegate] ||= self + + # search_bar = UISearchBar.alloc.initWithFrame(params[:frame]) + # search_bar.autoresizingMask = UIViewAutoresizingFlexibleWidth + + # if params[:search_bar] && params[:search_bar][:placeholder] + # search_bar.placeholder = params[:search_bar][:placeholder] + # end + + # @contacts_search_display_controller = UISearchDisplayController.alloc.initWithSearchBar(search_bar, contentsController: params[:content_controller]) + # @contacts_search_display_controller.delegate = params[:delegate] + # @contacts_search_display_controller.searchResultsDataSource = params[:data_source] + # @contacts_search_display_controller.searchResultsDelegate = params[:search_results_delegate] + + # self.table_view.tableHeaderView = search_bar + end + alias :makeRefreshable :make_refreshable + + ######### iOS methods, headless camel case ####### + + # UIRefreshControl Delegates + def refreshView(refresh) + refresh.attributedTitle = NSAttributedString.alloc.initWithString("Refreshing data...") + @on_refresh.call if @on_refresh + end + + def on_refresh(&block) + @on_refresh = block + end + + def end_refreshing + return unless @refresh + + @refresh.attributedTitle = NSAttributedString.alloc.initWithString("Last updated on #{Time.now.strftime("%H:%M:%S")}") + @refresh.endRefreshing + self.update_table_data + end + end +end \ No newline at end of file diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index f514a61..990f210 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -7,6 +7,9 @@ module ProMotion::MotionTable if self.class.respond_to?(:get_searchable) && self.class.get_searchable self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params) end + if self.class.respond_to?(:get_refreshable) && self.class.get_refreshable + self.make_refreshable + end end # @param [Array] Array of table data diff --git a/lib/ProMotion/screen_helpers/_tables/grouped_table.rb b/lib/ProMotion/screen_helpers/_tables/grouped_table.rb index 07e877f..09fb665 100644 --- a/lib/ProMotion/screen_helpers/_tables/grouped_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/grouped_table.rb @@ -1,6 +1,7 @@ module ProMotion::MotionTable module GroupedTable include SectionedTable + include RefreshableTable def table_view @table_view ||= UITableView.alloc.initWithFrame(self.view.frame, style:UITableViewStyleGrouped) diff --git a/lib/ProMotion/screen_helpers/_tables/plain_table.rb b/lib/ProMotion/screen_helpers/_tables/plain_table.rb index 11c5534..d837ac2 100644 --- a/lib/ProMotion/screen_helpers/_tables/plain_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/plain_table.rb @@ -2,6 +2,7 @@ module ProMotion::MotionTable module PlainTable include SectionedTable include SearchableTable + include RefreshableTable def table_view @table_view ||= UITableView.alloc.initWithFrame(self.view.frame, style:UITableViewStylePlain) diff --git a/lib/ProMotion/screens/_table_screen_module.rb b/lib/ProMotion/screens/_table_screen_module.rb index 925fb56..fb79460 100644 --- a/lib/ProMotion/screens/_table_screen_module.rb +++ b/lib/ProMotion/screens/_table_screen_module.rb @@ -2,6 +2,7 @@ module ProMotion module TableScreenModule include MotionTable::PlainTable include MotionTable::SearchableTable + include MotionTable::RefreshableTable include ProMotion::ScreenModule def update_table_data @@ -9,6 +10,7 @@ module ProMotion end module TableClassMethods + # Searchable def searchable(params={}) @searchable_params = params @searchable = true @@ -21,6 +23,17 @@ module ProMotion def get_searchable @searchable ||= false end + + # Refreshable + def refreshable(&block) + @refreshable_block = block + @refreshable = true + end + + def get_refreshable + @refreshable ||= false + end + end def self.included(base) base.extend(ClassMethods) From adfe258aab4c2f62c40260b890775cfccc1b7861 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 13:03:50 -0400 Subject: [PATCH 05/25] Update readme with implementation details for refreshing a tableview. --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index bc90486..4704446 100644 --- a/README.md +++ b/README.md @@ -684,6 +684,14 @@ end searchable(placeholder: "placeholder text") Class method to make the current table searchable. + + refreshable + Class method to make the current table refreshable.

You must also specify the following block in your will_appear method:

+ on_refresh do
+ # Code to start the refresh
+ end
+

And after you're done refreshing everything, call end_refreshing and your tableview will refresh the data automatically.

+

table_data

From f46aeea0d8190d32a2df1ad8a3c1d390ecdff77e Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 13:41:19 -0400 Subject: [PATCH 06/25] Make sure that we're running on ios6 or higher --- .../_tables/_refreshable_table.rb | 26 ------------------- .../_tables/_sectioned_table.rb | 2 +- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index bb29a86..c2fa041 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -5,32 +5,6 @@ module ProMotion::MotionTable @refresh.attributedTitle = NSAttributedString.alloc.initWithString("Pull to Refresh") @refresh.addTarget(self, action:'refreshView:', forControlEvents:UIControlEventValueChanged) self.refreshControl = @refresh - # @on_refresh = get_refreshable_block - - - # params[:content_controller] ||= params[:contentController] - # params[:data_source] ||= params[:searchResultsDataSource] - # params[:search_results_delegate] ||= params[:searchResultsDelegate] - - # params[:frame] ||= CGRectMake(0, 0, 320, 44) # TODO: Don't hardcode this... - # params[:content_controller] ||= self - # params[:delegate] ||= self - # params[:data_source] ||= self - # params[:search_results_delegate] ||= self - - # search_bar = UISearchBar.alloc.initWithFrame(params[:frame]) - # search_bar.autoresizingMask = UIViewAutoresizingFlexibleWidth - - # if params[:search_bar] && params[:search_bar][:placeholder] - # search_bar.placeholder = params[:search_bar][:placeholder] - # end - - # @contacts_search_display_controller = UISearchDisplayController.alloc.initWithSearchBar(search_bar, contentsController: params[:content_controller]) - # @contacts_search_display_controller.delegate = params[:delegate] - # @contacts_search_display_controller.searchResultsDataSource = params[:data_source] - # @contacts_search_display_controller.searchResultsDelegate = params[:search_results_delegate] - - # self.table_view.tableHeaderView = search_bar end alias :makeRefreshable :make_refreshable diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index 990f210..b0ef431 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -7,7 +7,7 @@ module ProMotion::MotionTable if self.class.respond_to?(:get_searchable) && self.class.get_searchable self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params) end - if self.class.respond_to?(:get_refreshable) && self.class.get_refreshable + if ios_version_greater_eq?("6.0") && self.class.respond_to?(:get_refreshable) && self.class.get_refreshable self.make_refreshable end end From c96a4a537d0ebca38a4ee535fa3b48e45eef1b58 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 13:43:14 -0400 Subject: [PATCH 07/25] fix readme typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4704446..99be9f7 100644 --- a/README.md +++ b/README.md @@ -688,7 +688,7 @@ end refreshable Class method to make the current table refreshable.

You must also specify the following block in your will_appear method:

on_refresh do
- # Code to start the refresh
+ # Code to start the refresh
end

And after you're done refreshing everything, call end_refreshing and your tableview will refresh the data automatically.

From 0d6cd7227e05a74d6ea58fd10160fd6ef4f2c42a Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 13:44:26 -0400 Subject: [PATCH 08/25] Better readme formatting for refreshable. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 99be9f7..b5b6f9b 100644 --- a/README.md +++ b/README.md @@ -687,9 +687,9 @@ end refreshable Class method to make the current table refreshable.

You must also specify the following block in your will_appear method:

- on_refresh do
- # Code to start the refresh
- end
+
on_refresh do
+  # Code to start the refresh
+end

And after you're done refreshing everything, call end_refreshing and your tableview will refresh the data automatically.

From 5a57ab6005d15d77b5e81ec4943719556a381e6b Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 19:30:07 -0400 Subject: [PATCH 09/25] Made callback pattern more consistent. Made all strings configurable. Updated documentation. --- README.md | 15 ++++++++---- .../_tables/_refreshable_table.rb | 23 ++++++++++++------- .../_tables/_sectioned_table.rb | 2 +- lib/ProMotion/screens/_table_screen_module.rb | 10 ++++++-- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b5b6f9b..6d33ed7 100644 --- a/README.md +++ b/README.md @@ -685,12 +685,19 @@ end Class method to make the current table searchable. - refreshable - Class method to make the current table refreshable.

You must also specify the following block in your will_appear method:

-
on_refresh do
+    
refreshable(
+  callback: :on_refresh,
+  pull_message: "Pull to refresh", 
+  refreshing: "Refreshing data…", 
+  updated_format: "Last updated at %s", 
+  updated_time_format: "%l:%M %p"
+)
+ Class method to make the current table refreshable. +

All parameters are optional. If you do not specify a a callback, it will assume you've implemented an on_refresh method in your tableview.

+
def on_refresh
   # Code to start the refresh
 end
-

And after you're done refreshing everything, call end_refreshing and your tableview will refresh the data automatically.

+

And after you're done with your asyncronous process, call end_refreshing to collapse the refresh view and update the last refreshed time and then update_table_data.

diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index c2fa041..ee9792a 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -1,8 +1,14 @@ module ProMotion::MotionTable module RefreshableTable - def make_refreshable + def make_refreshable(params={}) + pull_message = params[:pull_message] || "Pull to refresh" + @refreshing = params[:refreshing] || "Refreshing data..." + @updated_format = params[:updated_format] || "Last updated at %s" + @updated_time_format = params[:updated_time_format] || "%l:%M %p" + @refreshable_callback = params[:callback] + @refresh = UIRefreshControl.alloc.init - @refresh.attributedTitle = NSAttributedString.alloc.initWithString("Pull to Refresh") + @refresh.attributedTitle = NSAttributedString.alloc.initWithString(pull_message) @refresh.addTarget(self, action:'refreshView:', forControlEvents:UIControlEventValueChanged) self.refreshControl = @refresh end @@ -12,20 +18,21 @@ module ProMotion::MotionTable # UIRefreshControl Delegates def refreshView(refresh) - refresh.attributedTitle = NSAttributedString.alloc.initWithString("Refreshing data...") - @on_refresh.call if @on_refresh + refresh.attributedTitle = NSAttributedString.alloc.initWithString(@refreshing) + self.send(@refreshable_callback) if @refreshable_callback end - def on_refresh(&block) - @on_refresh = block + def start_refreshing + return unless @refresh + + @refresh.beginRefreshing end def end_refreshing return unless @refresh - @refresh.attributedTitle = NSAttributedString.alloc.initWithString("Last updated on #{Time.now.strftime("%H:%M:%S")}") + @refresh.attributedTitle = NSAttributedString.alloc.initWithString(sprintf(@updated_format, Time.now.strftime(@updated_time_format))) @refresh.endRefreshing - self.update_table_data end end end \ No newline at end of file diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index b0ef431..8f296b1 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -8,7 +8,7 @@ module ProMotion::MotionTable self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params) end if ios_version_greater_eq?("6.0") && self.class.respond_to?(:get_refreshable) && self.class.get_refreshable - self.make_refreshable + self.make_refreshable(self.class.get_refreshable_params) end end diff --git a/lib/ProMotion/screens/_table_screen_module.rb b/lib/ProMotion/screens/_table_screen_module.rb index fb79460..b88862c 100644 --- a/lib/ProMotion/screens/_table_screen_module.rb +++ b/lib/ProMotion/screens/_table_screen_module.rb @@ -25,8 +25,10 @@ module ProMotion end # Refreshable - def refreshable(&block) - @refreshable_block = block + def refreshable(params = {}) + params[:callback] = :on_refresh unless params[:callback] + + @refreshable_params = params @refreshable = true end @@ -34,6 +36,10 @@ module ProMotion @refreshable ||= false end + def get_refreshable_params + @refreshable_params ||= nil + end + end def self.included(base) base.extend(ClassMethods) From 45d726133cb6e9527d587b383b4f0eac4cd670b9 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 19:38:18 -0400 Subject: [PATCH 10/25] Add a warning if the user didn't implement the on_refresh method or they specified a callback method but didn't implement it. --- lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index ee9792a..3dcce4b 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -19,7 +19,11 @@ module ProMotion::MotionTable # UIRefreshControl Delegates def refreshView(refresh) refresh.attributedTitle = NSAttributedString.alloc.initWithString(@refreshing) - self.send(@refreshable_callback) if @refreshable_callback + if @refreshable_callback && self.respondsToSelector(@refreshable_callback) + self.send(@refreshable_callback) + else + ProMotion::Console.log("ProMotion Warning: you must implement an on_refresh method in your TableScreen.", with_color: ProMotion::Console::RED_COLOR) + end end def start_refreshing From 7df301e20dd9acc0d85a6329bd7bc8f5232c0eb9 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 22:03:55 -0400 Subject: [PATCH 11/25] Use more ruby syntax instead of Obj-C syntax. --- lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index 3dcce4b..d892ddb 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -19,7 +19,7 @@ module ProMotion::MotionTable # UIRefreshControl Delegates def refreshView(refresh) refresh.attributedTitle = NSAttributedString.alloc.initWithString(@refreshing) - if @refreshable_callback && self.respondsToSelector(@refreshable_callback) + if @refreshable_callback && self.respond_to?(@refreshable_callback) self.send(@refreshable_callback) else ProMotion::Console.log("ProMotion Warning: you must implement an on_refresh method in your TableScreen.", with_color: ProMotion::Console::RED_COLOR) From c6707f938b97c83387cf1372e53672e73c65f1a2 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 22:04:29 -0400 Subject: [PATCH 12/25] Modify console log to name the actual on_refresh method they need to implement if they defined a different callback. --- lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index d892ddb..e8eca83 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -22,7 +22,7 @@ module ProMotion::MotionTable if @refreshable_callback && self.respond_to?(@refreshable_callback) self.send(@refreshable_callback) else - ProMotion::Console.log("ProMotion Warning: you must implement an on_refresh method in your TableScreen.", with_color: ProMotion::Console::RED_COLOR) + ProMotion::Console.log("ProMotion Warning: you must implement the '#{@refreshable_callback}' method in your TableScreen.", with_color: ProMotion::Console::RED_COLOR) end end From 1a1918eb12fdeea3f2f39fd6636af179395b35d9 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 22:07:42 -0400 Subject: [PATCH 13/25] Better handling of the callback param. --- lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb | 2 +- lib/ProMotion/screens/_table_screen_module.rb | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index e8eca83..a8fc438 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -5,7 +5,7 @@ module ProMotion::MotionTable @refreshing = params[:refreshing] || "Refreshing data..." @updated_format = params[:updated_format] || "Last updated at %s" @updated_time_format = params[:updated_time_format] || "%l:%M %p" - @refreshable_callback = params[:callback] + @refreshable_callback = params[:callback]|| :on_refresh @refresh = UIRefreshControl.alloc.init @refresh.attributedTitle = NSAttributedString.alloc.initWithString(pull_message) diff --git a/lib/ProMotion/screens/_table_screen_module.rb b/lib/ProMotion/screens/_table_screen_module.rb index b88862c..890182c 100644 --- a/lib/ProMotion/screens/_table_screen_module.rb +++ b/lib/ProMotion/screens/_table_screen_module.rb @@ -26,8 +26,6 @@ module ProMotion # Refreshable def refreshable(params = {}) - params[:callback] = :on_refresh unless params[:callback] - @refreshable_params = params @refreshable = true end From d514555de65a969e88ded860dfc52ee7b5332397 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Mon, 6 May 2013 22:26:10 -0400 Subject: [PATCH 14/25] Huzzah! Works brilliantly in ios 6 and ios 5 now! --- lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index 8f296b1..3de4875 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -7,8 +7,10 @@ module ProMotion::MotionTable if self.class.respond_to?(:get_searchable) && self.class.get_searchable self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params) end - if ios_version_greater_eq?("6.0") && self.class.respond_to?(:get_refreshable) && self.class.get_refreshable + if defined?(UIRefreshControl) && self.class.respond_to?(:get_refreshable) && self.class.get_refreshable self.make_refreshable(self.class.get_refreshable_params) + else + ProMotion::Console.log("ProMotion Warning: to use the refresh control on < iOS 6, you need to include the Cocoapod 'CKRefreshControl'.", with_color: ProMotion::Console::RED_COLOR) end end From a0e783bbb00e457e8f349ebfd7585f13cd89e15d Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Mon, 6 May 2013 20:54:59 -0700 Subject: [PATCH 15/25] Added an method for adding any view to any other parent view with attributes. Closes issue #18. --- README.md | 15 ++++++++++++++ .../screen_helpers/screen_elements.rb | 20 ++++++++++--------- spec/screen_helpers_spec.rb | 12 +++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bc90486..c972750 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ Run `rake`. You should now see the simulator open with your home screen and a na * Added `open_split_screen` for iPad-supported apps (thanks @rheoli for your contributions to this) * `ProMotion::AppDelegateParent` renamed to `ProMotion::Delegate` (`AppDelegateParent` is an alias) +* Added `add_to` method for adding views to any parent view. `remove` works with this normally. # Usage @@ -329,6 +330,8 @@ Any view item (UIView, UIButton, custom UIView subclasses, etc) can be added to `add` accepts a second argument which is a hash of attributes that get applied to the element before it is dropped into the view. +`add(view, attr={})` + ```ruby @label = add UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), { text: "This is awesome!", @@ -342,12 +345,24 @@ dropped into the view. The `set_attributes` method is identical to add except that it does not add it to the current view. +`set_attributes(view, attr={})` + ```ruby @element = set_attributes UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), { backgroundColor: UIColor.whiteColor } ``` +You can use `add_to` to add a view to any other view, not just the main view. + +`add_to(parent_view, new_view, attr={})` + +```ruby +add_to @some_parent_view, UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), { + backgroundColor: UIColor.whiteColor +} +``` + ## Table Screens You can create sectioned table screens easily with TableScreen, SectionedTableScreen, and GroupedTableScreen. diff --git a/lib/ProMotion/screen_helpers/screen_elements.rb b/lib/ProMotion/screen_helpers/screen_elements.rb index 019cb67..4055850 100644 --- a/lib/ProMotion/screen_helpers/screen_elements.rb +++ b/lib/ProMotion/screen_helpers/screen_elements.rb @@ -2,22 +2,24 @@ module ProMotion module ScreenElements include ProMotion::ViewHelper - def add(v, attrs = {}) - if attrs && attrs.length > 0 - set_attributes(v, attrs) - end - self.view.addSubview(v) - v + def add(element, attrs = {}) + add_to self.view, element, attrs end alias :add_element :add alias :add_view :add - def remove(v) - v.removeFromSuperview - v = nil + def remove(element) + element.removeFromSuperview + element = nil end alias :remove_element :remove alias :remove_view :remove + + def add_to(parent_element, element, attrs = {}) + set_attributes(element, attrs) if attrs && attrs.length > 0 + parent_element.addSubview element + element + end def bounds return self.view.bounds diff --git a/spec/screen_helpers_spec.rb b/spec/screen_helpers_spec.rb index cc13c14..4edca1c 100644 --- a/spec/screen_helpers_spec.rb +++ b/spec/screen_helpers_spec.rb @@ -24,6 +24,18 @@ describe "screen helpers" do @screen.view.subviews.count.should == 0 end + it "should add a subview to another element" do + sub_subview = UIView.alloc.initWithFrame CGRectZero + @screen.add_to @subview, sub_subview + @subview.subviews.include?(sub_subview).should == true + end + + it "should add a subview to another element with attributes" do + sub_subview = UIView.alloc.initWithFrame CGRectZero + @screen.add_to @subview, sub_subview, { backgroundColor: UIColor.redColor } + @subview.subviews.last.backgroundColor.should == UIColor.redColor + end + end From 70e6e98c66c835b4233a0833d0ec3a17fc9793ec Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Mon, 6 May 2013 21:08:00 -0700 Subject: [PATCH 16/25] Minor refactors to clean up the screen module --- lib/ProMotion/screens/_screen_module.rb | 26 +++++++++++++------------ spec/screen_helpers_spec.rb | 19 +++++++++++++++++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/ProMotion/screens/_screen_module.rb b/lib/ProMotion/screens/_screen_module.rb index 5dc18c2..69657bd 100644 --- a/lib/ProMotion/screens/_screen_module.rb +++ b/lib/ProMotion/screens/_screen_module.rb @@ -60,23 +60,26 @@ module ProMotion end def set_nav_bar_right_button(title, args={}) - args[:style] ||= UIBarButtonItemStyleBordered - args[:target] ||= self - args[:action] ||= nil - - right_button = UIBarButtonItem.alloc.initWithTitle(title, style: args[:style], target: args[:target], action: args[:action]) - self.navigationItem.rightBarButtonItem = right_button - right_button + args[:title] = title + set_nav_bar_button :right, args end def set_nav_bar_left_button(title, args={}) + args[:title] = title + set_nav_bar_button :left, args + end + + def set_nav_bar_button(side, args={}) args[:style] ||= UIBarButtonItemStyleBordered args[:target] ||= self args[:action] ||= nil - left_button = UIBarButtonItem.alloc.initWithTitle(title, style: args[:style], target: args[:target], action: args[:action]) - self.navigationItem.leftBarButtonItem = left_button - left_button + button = UIBarButtonItem.alloc.initWithTitle(title, style: args[:style], target: args[:target], action: args[:action]) + + self.navigationItem.leftBarButtonItem = button if side == :left + self.navigationItem.rightBarButtonItem = button if side == :right + + button end # [DEPRECATED] @@ -132,8 +135,7 @@ module ProMotion end def main_controller - return self.navigation_controller if self.navigation_controller - self + self.navigation_controller || self end def view_controller diff --git a/spec/screen_helpers_spec.rb b/spec/screen_helpers_spec.rb index 4edca1c..56557f5 100644 --- a/spec/screen_helpers_spec.rb +++ b/spec/screen_helpers_spec.rb @@ -35,9 +35,26 @@ describe "screen helpers" do @screen.add_to @subview, sub_subview, { backgroundColor: UIColor.redColor } @subview.subviews.last.backgroundColor.should == UIColor.redColor end - + end + describe "nav bar buttons" do + + before do + @screen = HomeScreen.new(nav_bar: true) + end + + it "should add a left nav bar button" do + @screen.set_nav_bar_left_button "Save", action: :save_something, type: UIBarButtonItemStyleDone + @screen.navigationItem.leftBarButtonItem.class.should == UIBarButtonItem + end + + it "should add a right nav bar button" do + @screen.set_nav_bar_right_button "Cancel", action: :return_to_some_other_screen, type: UIBarButtonItemStylePlain + @screen.navigationItem.rightBarButtonItem.class.should == UIBarButtonItem + end + + end describe "screen navigation" do From 7d065510e3e846042caac253c2add8b4a6edb628 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Tue, 7 May 2013 00:21:58 -0400 Subject: [PATCH 17/25] Initial stab at tablescreen tests --- spec/helpers/.gitkeep | 0 spec/helpers/table_screen.rb | 44 ++++++++++++++++++++++++ spec/helpers/table_screen_refreshable.rb | 9 +++++ spec/helpers/table_screen_searchable.rb | 5 +++ spec/table_screen_spec.rb | 38 ++++++++++++++++++++ 5 files changed, 96 insertions(+) delete mode 100644 spec/helpers/.gitkeep create mode 100644 spec/helpers/table_screen.rb create mode 100644 spec/helpers/table_screen_refreshable.rb create mode 100644 spec/helpers/table_screen_searchable.rb create mode 100644 spec/table_screen_spec.rb diff --git a/spec/helpers/.gitkeep b/spec/helpers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/spec/helpers/table_screen.rb b/spec/helpers/table_screen.rb new file mode 100644 index 0000000..f16c3f8 --- /dev/null +++ b/spec/helpers/table_screen.rb @@ -0,0 +1,44 @@ +class TableScreen < ProMotion::SectionedTableScreen + + def on_load + @tap_counter ||= 0 + end + + def table_data + [{ + title: "Your Account", + cells: [ + { title: "Increment", action: :increment_counter_by, arguments: { number: 3 } }, + { title: "Add New Row", action: :add_tableview_row, accessibilityLabel: "Add New Row" }, + { title: "Just another blank row" } + ] + }, { + title: "App Stuff", + cells: [ + { title: "Increment One", action: :increment_counter }, + { title: "Feedback", remote_image: { url: "http://placekitten.com/100/100", placeholder: "some-local-image", size: 50, radius: 15 } } + ] + }] + end + + def edit_profile(args={}) + args[:id] + end + + def add_tableview_row + @data[0][:cells] << { + title: "Dynamically Added" + } + update_table_data + end + + def increment_counter + @tap_counter = @tap_counter + 1 + end + + def increment_counter_by(args) + @tap_counter = @tap_counter + args[:number] + end + + +end \ No newline at end of file diff --git a/spec/helpers/table_screen_refreshable.rb b/spec/helpers/table_screen_refreshable.rb new file mode 100644 index 0000000..74f1cb4 --- /dev/null +++ b/spec/helpers/table_screen_refreshable.rb @@ -0,0 +1,9 @@ +class TableScreenRefreshable < TableScreen + + refreshable + + def on_refresh + #do stuff + end + +end \ No newline at end of file diff --git a/spec/helpers/table_screen_searchable.rb b/spec/helpers/table_screen_searchable.rb new file mode 100644 index 0000000..13c282a --- /dev/null +++ b/spec/helpers/table_screen_searchable.rb @@ -0,0 +1,5 @@ +class TableScreenSearchable < TableScreen + + searchable + +end \ No newline at end of file diff --git a/spec/table_screen_spec.rb b/spec/table_screen_spec.rb new file mode 100644 index 0000000..0e8140a --- /dev/null +++ b/spec/table_screen_spec.rb @@ -0,0 +1,38 @@ +describe "table screen basic functionality" do + + before do + @screen = TableScreen.new + @screen.on_load + end + + tests TableScreen + + it "should display have 2 sections" do + @screen.tableView.numberOfSections.should == 2 + end + + it "should have prope r cell numbers" do + @screen.tableView.numberOfRowsInSection(0).should == 3 + @screen.tableView.numberOfRowsInSection(1).should == 2 + end + + # it "should run methods without arguments when tapping cell" do + # #cell = @screen.cell_at_section_and_index(0, 0) + # [1..10].each do |index| + # @screen.instance_variable_get("@tap_counter").should == index + # tap view("Increment") + # end + # end + + # it "should have a placeholder image in the last cell" do + # @screen.cell_at_section_and_index(1,1).imageView.should.be.a UIImage + # end + + # it "should add a new cell to first section" do + # tap "Add New Row" + # wait 0.2 do + # @screen.tableView.numberOfRowsInSection(0).should == 4 + # end + # end + +end From 9e4ea34cabab4f5b823b4aa9864b72c0face7c4f Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Mon, 6 May 2013 23:16:04 -0700 Subject: [PATCH 18/25] Updated table screen specs More work is needed on these. --- Rakefile | 2 +- app/app_delegate.rb | 3 + .../_tables/_refreshable_table.rb | 18 ++-- .../_tables/_sectioned_table.rb | 10 +- spec/helpers/table_screen.rb | 20 ++-- spec/helpers/table_screen_refreshable.rb | 4 +- spec/ios_version_spec.rb | 10 +- spec/table_screen_spec.rb | 98 +++++++++++++------ 8 files changed, 105 insertions(+), 60 deletions(-) diff --git a/Rakefile b/Rakefile index 5493320..4f25409 100644 --- a/Rakefile +++ b/Rakefile @@ -12,7 +12,7 @@ Motion::Project::App.setup do |app| app.redgreen_style = :focused # :focused, :full # Devices - app.deployment_target = "5.0" + app.deployment_target = "6.0" app.device_family = [:ipad] # so we can test split screen capability app.detect_dependencies = true diff --git a/app/app_delegate.rb b/app/app_delegate.rb index 83c7a7f..10d9b51 100644 --- a/app/app_delegate.rb +++ b/app/app_delegate.rb @@ -1,2 +1,5 @@ class AppDelegate + def application(application, didFinishLaunchingWithOptions:launchOptions) + return true if RUBYMOTION_ENV == 'test' + end end diff --git a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb index a8fc438..f2e7b74 100644 --- a/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_refreshable_table.rb @@ -7,10 +7,10 @@ module ProMotion::MotionTable @updated_time_format = params[:updated_time_format] || "%l:%M %p" @refreshable_callback = params[:callback]|| :on_refresh - @refresh = UIRefreshControl.alloc.init - @refresh.attributedTitle = NSAttributedString.alloc.initWithString(pull_message) - @refresh.addTarget(self, action:'refreshView:', forControlEvents:UIControlEventValueChanged) - self.refreshControl = @refresh + @refresh_control = UIRefreshControl.alloc.init + @refresh_control.attributedTitle = NSAttributedString.alloc.initWithString(pull_message) + @refresh_control.addTarget(self, action:'refreshView:', forControlEvents:UIControlEventValueChanged) + self.refreshControl = @refresh_control end alias :makeRefreshable :make_refreshable @@ -27,16 +27,16 @@ module ProMotion::MotionTable end def start_refreshing - return unless @refresh + return unless @refresh_control - @refresh.beginRefreshing + @refresh_control.beginRefreshing end def end_refreshing - return unless @refresh + return unless @refresh_control - @refresh.attributedTitle = NSAttributedString.alloc.initWithString(sprintf(@updated_format, Time.now.strftime(@updated_time_format))) - @refresh.endRefreshing + @refresh_control.attributedTitle = NSAttributedString.alloc.initWithString(sprintf(@updated_format, Time.now.strftime(@updated_time_format))) + @refresh_control.endRefreshing end end end \ No newline at end of file diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index 3de4875..1489533 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -7,10 +7,12 @@ module ProMotion::MotionTable if self.class.respond_to?(:get_searchable) && self.class.get_searchable self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params) end - if defined?(UIRefreshControl) && self.class.respond_to?(:get_refreshable) && self.class.get_refreshable - self.make_refreshable(self.class.get_refreshable_params) - else - ProMotion::Console.log("ProMotion Warning: to use the refresh control on < iOS 6, you need to include the Cocoapod 'CKRefreshControl'.", with_color: ProMotion::Console::RED_COLOR) + if self.class.respond_to?(:get_refreshable) && self.class.get_refreshable + if defined?(UIRefreshControl) + self.make_refreshable(self.class.get_refreshable_params) + else + ProMotion::Console.log("ProMotion Warning: to use the refresh control on < iOS 6, you need to include the Cocoapod 'CKRefreshControl'.", with_color: ProMotion::Console::RED_COLOR) + end end end diff --git a/spec/helpers/table_screen.rb b/spec/helpers/table_screen.rb index f16c3f8..dccc456 100644 --- a/spec/helpers/table_screen.rb +++ b/spec/helpers/table_screen.rb @@ -1,11 +1,11 @@ class TableScreen < ProMotion::SectionedTableScreen def on_load - @tap_counter ||= 0 + @tap_counter ||= 0 end def table_data - [{ + [{ title: "Your Account", cells: [ { title: "Increment", action: :increment_counter_by, arguments: { number: 3 } }, @@ -26,18 +26,22 @@ class TableScreen < ProMotion::SectionedTableScreen end def add_tableview_row - @data[0][:cells] << { - title: "Dynamically Added" - } - update_table_data + @data[0][:cells] << { + title: "Dynamically Added" + } + update_table_data end def increment_counter - @tap_counter = @tap_counter + 1 + @tap_counter += 1 end def increment_counter_by(args) - @tap_counter = @tap_counter + args[:number] + @tap_counter = @tap_counter + args[:number] + end + + def tap_counter + @tap_counter end diff --git a/spec/helpers/table_screen_refreshable.rb b/spec/helpers/table_screen_refreshable.rb index 74f1cb4..519dadc 100644 --- a/spec/helpers/table_screen_refreshable.rb +++ b/spec/helpers/table_screen_refreshable.rb @@ -1,9 +1,11 @@ class TableScreenRefreshable < TableScreen + attr_accessor :on_refresh_called refreshable def on_refresh - #do stuff + self.on_refresh_called = true + end_refreshing end end \ No newline at end of file diff --git a/spec/ios_version_spec.rb b/spec/ios_version_spec.rb index 3e2884a..7efd155 100644 --- a/spec/ios_version_spec.rb +++ b/spec/ios_version_spec.rb @@ -6,23 +6,23 @@ describe "ios version" do end it "#ios_version_is?" do - @dummy.ios_version_is?(@dummy.ios_version).should == true + @dummy.ios_version_is?(@dummy.ios_version).should.be.true end it "#ios_version_greater?" do - @dummy.ios_version_greater?('1.0').should == true + @dummy.ios_version_greater?('1.0').should.be.true end it "#ios_version_greater_eq?" do - @dummy.ios_version_greater_eq?(@dummy.ios_version).should == true + @dummy.ios_version_greater_eq?(@dummy.ios_version).should.be.true end it "#ios_version_less?" do - @dummy.ios_version_less?('9.0').should == true + @dummy.ios_version_less?('9.0').should.be.true end it "#ios_version_less_eq?" do - @dummy.ios_version_less_eq?(@dummy.ios_version).should == true + @dummy.ios_version_less_eq?(@dummy.ios_version).should.be.true end end diff --git a/spec/table_screen_spec.rb b/spec/table_screen_spec.rb index 0e8140a..8528315 100644 --- a/spec/table_screen_spec.rb +++ b/spec/table_screen_spec.rb @@ -1,38 +1,72 @@ -describe "table screen basic functionality" do +describe "table screens" do + + describe "basic functionality" do - before do - @screen = TableScreen.new - @screen.on_load + before do + UIView.setAnimationsEnabled false # avoid animation issues + + @screen = TableScreen.new + @screen.on_load + end + + it "should display 2 sections" do + @screen.tableView.numberOfSections.should == 2 + end + + it "should have proper cell numbers" do + @screen.tableView.numberOfRowsInSection(0).should == 3 + @screen.tableView.numberOfRowsInSection(1).should == 2 + end + + it "should have a placeholder image in the last cell" do + index_path = NSIndexPath.indexPathForRow(1, inSection: 1) + + @screen.tableView(@screen.tableView, cellForRowAtIndexPath: index_path).imageView.class.should == UIImageView + end + + end + + describe "search functionality" do + + before do + @screen = TableScreenSearchable.new + @screen.on_load + end + + it "should be searchable" do + @screen.class.get_searchable.should == true + end + + it "should create a search header" do + @screen.table_view.tableHeaderView.class.should == UISearchBar + end + end - tests TableScreen - - it "should display have 2 sections" do - @screen.tableView.numberOfSections.should == 2 + describe "refresh functionality" do + + # Note this test only works if on iOS 6+ or when using CKRefreshControl. + + before do + @screen = TableScreenRefreshable.new + @screen.on_load + end + + it "should be refreshable" do + @screen.class.get_refreshable.should == true + end + + it "should create a refresh object" do + @screen.instance_variable_get("@refresh_control").class.should == UIRefreshControl + end + + it "should respond to start_refreshing and end_refreshing" do + @screen.respond_to?(:start_refreshing).should == true + @screen.respond_to?(:end_refreshing).should == true + end + + # Animations cause the refresh object to fail when tested. Test manually. + end - it "should have prope r cell numbers" do - @screen.tableView.numberOfRowsInSection(0).should == 3 - @screen.tableView.numberOfRowsInSection(1).should == 2 - end - - # it "should run methods without arguments when tapping cell" do - # #cell = @screen.cell_at_section_and_index(0, 0) - # [1..10].each do |index| - # @screen.instance_variable_get("@tap_counter").should == index - # tap view("Increment") - # end - # end - - # it "should have a placeholder image in the last cell" do - # @screen.cell_at_section_and_index(1,1).imageView.should.be.a UIImage - # end - - # it "should add a new cell to first section" do - # tap "Add New Row" - # wait 0.2 do - # @screen.tableView.numberOfRowsInSection(0).should == 4 - # end - # end - end From 590f29d9fc6afb31fd4d6627264c99061639f4b6 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 7 May 2013 14:51:11 -0700 Subject: [PATCH 19/25] `set_easy_attributes` now working. autoresizingMask and frame are the first improvements this brings. --- lib/ProMotion/helpers/view_helper.rb | 26 +++++++ .../screen_helpers/screen_elements.rb | 5 +- spec/view_helper_spec.rb | 70 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/lib/ProMotion/helpers/view_helper.rb b/lib/ProMotion/helpers/view_helper.rb index b7c1920..e639fd8 100644 --- a/lib/ProMotion/helpers/view_helper.rb +++ b/lib/ProMotion/helpers/view_helper.rb @@ -11,6 +11,28 @@ module ProMotion element.send("#{k}=", v) if element.respond_to?("#{k}=") end end + + element + end + + def set_easy_attributes(parent, element, args={}) + attributes = {} + + if args[:resize] + attributes[:autoresizingMask] = UIViewAutoresizingNone + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleLeftMargin if args[:resize].include?(:left) + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleRightMargin if args[:resize].include?(:right) + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleTopMargin if args[:resize].include?(:top) + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleBottomMargin if args[:resize].include?(:bottom) + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleWidth if args[:resize].include?(:width) + attributes[:autoresizingMask] |= UIViewAutoresizingFlexibleHeight if args[:resize].include?(:height) + end + + if [:left, :top, :width, :height].select{ |a| args[a] && args[a] != :auto }.length == 4 + attributes[:frame] = CGRectMake(args[:left], args[:top], args[:width], args[:height]) + end + + set_attributes element, attributes element end @@ -32,5 +54,9 @@ module ProMotion end height end + + def positioning_attributes(attr={}) + + end end end \ No newline at end of file diff --git a/lib/ProMotion/screen_helpers/screen_elements.rb b/lib/ProMotion/screen_helpers/screen_elements.rb index 4055850..2d189cb 100644 --- a/lib/ProMotion/screen_helpers/screen_elements.rb +++ b/lib/ProMotion/screen_helpers/screen_elements.rb @@ -16,7 +16,10 @@ module ProMotion alias :remove_view :remove def add_to(parent_element, element, attrs = {}) - set_attributes(element, attrs) if attrs && attrs.length > 0 + if attrs && attrs.length > 0 + set_attributes(element, attrs) + set_easy_attributes(parent_element, element, attrs) + end parent_element.addSubview element element end diff --git a/spec/view_helper_spec.rb b/spec/view_helper_spec.rb index f243e7b..2628def 100644 --- a/spec/view_helper_spec.rb +++ b/spec/view_helper_spec.rb @@ -67,4 +67,74 @@ describe "view helpers" do end + describe "set_easy_attributes" do + + before do + @dummy = UIView.alloc.initWithFrame CGRectZero + @dummy.extend ProMotion::ViewHelper + + @parent = UIView.alloc.initWithFrame(CGRectMake(0, 0, 320, 480)) + @child = UIView.alloc.initWithFrame(CGRectZero) + end + + it "Should set the autoresizingMask for all" do + @dummy.set_easy_attributes @parent, @child, { + resize: [:left, :right, :top, :bottom, :width, :height] + } + + mask = UIViewAutoresizingFlexibleLeftMargin | + UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleBottomMargin | + UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight + + @child.autoresizingMask.should == mask + end + + it "Should set the autoresizingMask for half" do + @dummy.set_easy_attributes @parent, @child, { + resize: [:left, :right, :top] + } + + mask = UIViewAutoresizingFlexibleLeftMargin | + UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleTopMargin + + @child.autoresizingMask.should == mask + end + + it "Should set the autoresizingMask for the second half" do + @dummy.set_easy_attributes @parent, @child, { + resize: [:bottom, :width, :height] + } + + mask = UIViewAutoresizingFlexibleBottomMargin | + UIViewAutoresizingFlexibleWidth | + UIViewAutoresizingFlexibleHeight + + @child.autoresizingMask.should == mask + end + + it "Should not set the autoresizingMask" do + @dummy.set_easy_attributes @parent, @child, {} + + mask = UIViewAutoresizingNone + + @child.autoresizingMask.should == mask + end + + it "Should create a frame" do + @dummy.set_easy_attributes @parent, @child, { + left: 10, + top: 20, + width: 100, + height: 50 + } + + @child.frame.should == CGRectMake(10, 20, 100, 50) + end + + end + end From 84991ae6b42e35467a46628ebe7f1133d7e0496a Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 7 May 2013 14:53:36 -0700 Subject: [PATCH 20/25] README update for add improvements --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 12c51bb..770279d 100644 --- a/README.md +++ b/README.md @@ -333,9 +333,14 @@ dropped into the view. `add(view, attr={})` ```ruby -@label = add UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), { +@label = add UILabel.new, { text: "This is awesome!", - font: UIFont.systemFontOfSize(18) + font: UIFont.systemFontOfSize(18), + resize: [ :left, :right, :top, :bottom, :width, :height ], # autoresizingMask + left: 5, # These four attributes are used with CGRectMake + top: 5, + width: 20, + height: 20 } @element = add UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), { From 09772933d75a4823b8838da7e8f4dde2dac2d333 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 7 May 2013 15:39:49 -0700 Subject: [PATCH 21/25] Fixing bug in set_nav_bar button methods --- lib/ProMotion/screens/_screen_module.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ProMotion/screens/_screen_module.rb b/lib/ProMotion/screens/_screen_module.rb index 69657bd..b010b6c 100644 --- a/lib/ProMotion/screens/_screen_module.rb +++ b/lib/ProMotion/screens/_screen_module.rb @@ -74,7 +74,7 @@ module ProMotion args[:target] ||= self args[:action] ||= nil - button = UIBarButtonItem.alloc.initWithTitle(title, style: args[:style], target: args[:target], action: args[:action]) + button = UIBarButtonItem.alloc.initWithTitle(args[:title], style: args[:style], target: args[:target], action: args[:action]) self.navigationItem.leftBarButtonItem = button if side == :left self.navigationItem.rightBarButtonItem = button if side == :right From 276496912aba97b5a6120e795306569882358312 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 7 May 2013 16:13:21 -0700 Subject: [PATCH 22/25] Use snake_case for Objective-C methods. Fixes Issue #56. --- README.md | 5 ++++- lib/ProMotion/helpers/view_helper.rb | 28 +++++++++++++++++++--------- spec/view_helper_spec.rb | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 770279d..4405f65 100644 --- a/README.md +++ b/README.md @@ -349,12 +349,15 @@ dropped into the view. ``` The `set_attributes` method is identical to add except that it does not add it to the current view. +If you use snake_case and there isn't an existing method, it'll try camelCase. This allows you to +use snake_case for Objective-C methods. `set_attributes(view, attr={})` ```ruby @element = set_attributes UIView.alloc.initWithFrame(CGRectMake(0, 0, 20, 20)), { - backgroundColor: UIColor.whiteColor + # `background_color` is translated to `backgroundColor` automatically. + background_color: UIColor.whiteColor } ``` diff --git a/lib/ProMotion/helpers/view_helper.rb b/lib/ProMotion/helpers/view_helper.rb index e639fd8..47b2f96 100644 --- a/lib/ProMotion/helpers/view_helper.rb +++ b/lib/ProMotion/helpers/view_helper.rb @@ -1,18 +1,28 @@ module ProMotion module ViewHelper def set_attributes(element, args = {}) - args.each do |k, v| - if v.is_a? Hash - sub_element = element.send(k) - set_attributes sub_element, v - elsif v.is_a? Array - element.send("#{k}", *v) if element.respond_to?("#{k}") - else - element.send("#{k}=", v) if element.respond_to?("#{k}=") + args.each { |k, v| set_attribute(element, k, v) } + element + end + + def set_attribute(element, k, v) + if v.is_a?(Hash) && element.respond_to?(k) + sub_element = element.send(k) + set_attributes sub_element, v + elsif v.is_a?(Array) && element.respond_to?("#{k}") + element.send("#{k}", *v) + elsif element.respond_to?("#{k}=") + element.send("#{k}=", v) + else + # Doesn't respond. Check if snake case. + if k.to_s.include?("_") + set_attribute(element, objective_c_method_name(k), v) end end + end - element + def objective_c_method_name(meth) + meth.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join end def set_easy_attributes(parent, element, args={}) diff --git a/spec/view_helper_spec.rb b/spec/view_helper_spec.rb index 2628def..65cf806 100644 --- a/spec/view_helper_spec.rb +++ b/spec/view_helper_spec.rb @@ -49,6 +49,21 @@ describe "view helpers" do layered_view.layer.mask.backgroundColor.should == UIColor.redColor.CGColor end + it "should allow you to set snake_case attributes" do + layered_view = UIView.alloc.initWithFrame(CGRectMake(0, 0, 10, 10)) + + @dummy.set_attributes layered_view, { + layer: { + background_color: UIColor.redColor.CGColor + }, + content_mode: UIViewContentModeBottom + } + + layered_view.contentMode.should == UIViewContentModeBottom + layered_view.layer.backgroundColor.should == UIColor.redColor.CGColor + end + + describe "content height" do before do From 9428b1bb753802b05b075b915d90052df21d8fa1 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 7 May 2013 16:18:27 -0700 Subject: [PATCH 23/25] Return element after set_attribute. --- lib/ProMotion/helpers/view_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ProMotion/helpers/view_helper.rb b/lib/ProMotion/helpers/view_helper.rb index 47b2f96..18028a1 100644 --- a/lib/ProMotion/helpers/view_helper.rb +++ b/lib/ProMotion/helpers/view_helper.rb @@ -19,6 +19,7 @@ module ProMotion set_attribute(element, objective_c_method_name(k), v) end end + element end def objective_c_method_name(meth) From be8da5662e2af2b7c89157d5cb902334542f79ed Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Tue, 7 May 2013 22:20:39 -0400 Subject: [PATCH 24/25] Allow the user to specify individual cell height in the cell hash. If not specified, the cell with use the tableView.rowHeight property. --- lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb index 1489533..538df62 100644 --- a/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb +++ b/lib/ProMotion/screen_helpers/_tables/_sectioned_table.rb @@ -261,6 +261,15 @@ module ProMotion::MotionTable return table_cell end + def tableView(tableView, heightForRowAtIndexPath:indexPath) + cell = cell_at_section_and_index(indexPath.section, indexPath.row) + if cell[:height] + cell[:height].to_f + else + tableView.rowHeight + end + end + def tableView(table_view, didSelectRowAtIndexPath:indexPath) cell = cell_at_section_and_index(indexPath.section, indexPath.row) table_view.deselectRowAtIndexPath(indexPath, animated: true); From 3b37613b95a7bc46b9b2ca2cc0217ee1f1a5388b Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Tue, 7 May 2013 22:47:16 -0400 Subject: [PATCH 25/25] Added example to readme for cell height. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 770279d..4f79383 100644 --- a/README.md +++ b/README.md @@ -744,6 +744,7 @@ def table_data subtitle: "This is way too huge..see note", arguments: { data: [ "lots", "of", "data" ] }, action: :tapped_cell_1, + height: 50, # manually changes the cell's height cell_style: UITableViewCellStyleSubtitle, cell_identifier: "Cell", cell_class: ProMotion::TableViewCell,