ProMotion 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -7
- data/lib/ProMotion/screen/nav_bar_module.rb +6 -2
- data/lib/ProMotion/screen/screen_module.rb +38 -0
- data/lib/ProMotion/styling/styling.rb +3 -1
- data/lib/ProMotion/table/cell/table_view_cell_module.rb +1 -1
- data/lib/ProMotion/table/data/table_data.rb +4 -0
- data/lib/ProMotion/table/extensions/longpressable.rb +1 -0
- data/lib/ProMotion/table/extensions/refreshable.rb +3 -0
- data/lib/ProMotion/table/table.rb +95 -16
- data/lib/ProMotion/version.rb +1 -1
- data/spec/functional/func_table_screen_cell_spec.rb +44 -0
- data/spec/functional/func_table_screen_spec.rb +2 -2
- data/spec/unit/screen_spec.rb +42 -0
- data/spec/unit/tables/table_module_spec.rb +4 -0
- data/spec/unit/tables/table_screen_spec.rb +110 -0
- data/spec/unit/view_helper_spec.rb +25 -0
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 37daeda0dc99301ea7bb1fd7ab847e3fd1803cb1
         | 
| 4 | 
            +
              data.tar.gz: 420f59061a730bb933e13a3fa0737be210be85de
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 615447c2fffa5b940a792db69c5cac17d37f9b617323e5cc64cbdbf40f1007b8aff1bd8650e66d67400049e8cfb5f76a3d3543376c62cdd930c596e07aa126f4
         | 
| 7 | 
            +
              data.tar.gz: 0275defb4b361f3ea70d3bb6f69ba5a78017dc271a40125f796083ee83cd57d3a63d4bcdefaab165b57c8790ad15a8f536bc3a150ccffb3d3cac77bc151b6c41
         | 
    
        data/README.md
    CHANGED
    
    | @@ -90,13 +90,18 @@ end | |
| 90 90 |  | 
| 91 91 | 
             
            # Changelog
         | 
| 92 92 |  | 
| 93 | 
            -
            ## Version 2. | 
| 94 | 
            -
             | 
| 95 | 
            -
            This release includes  | 
| 96 | 
            -
             | 
| 97 | 
            -
            *  | 
| 98 | 
            -
            *  | 
| 99 | 
            -
            *  | 
| 93 | 
            +
            ## Version 2.2.0
         | 
| 94 | 
            +
             | 
| 95 | 
            +
            This release includes several new features and is backwards compatible with all 2.x releases.
         | 
| 96 | 
            +
             | 
| 97 | 
            +
            * PM::TableScreen: You can now set a custom table view header view ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/556))
         | 
| 98 | 
            +
            * PM::TableScreen refreshable: Refresh controls now show when programmatically initiating refresh ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
         | 
| 99 | 
            +
            * PM::TableScreen: Added reorderable ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/569))
         | 
| 100 | 
            +
            * PM::TableScreen: Added auto height feature ([thanks Carlin Isaacson](https://github.com/clearsightstudio/ProMotion/pull/574))
         | 
| 101 | 
            +
            * PM::Screen: The navigation controller bottom toolbar will auto-hide when passed nil or false ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/577))
         | 
| 102 | 
            +
            * PM::Screen: You can now choose a status bar style ([thanks Mark Rickert](https://github.com/clearsightstudio/ProMotion/pull/563))
         | 
| 103 | 
            +
            * Added `on_load` and `on_styled` hooks for UIViews that implement those methods ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/567))
         | 
| 104 | 
            +
            * Fixed an issue where cell properties would be applied twice unnecessarily ([Jamon Holmgren](https://github.com/clearsightstudio/ProMotion/pull/573))
         | 
| 100 105 |  | 
| 101 106 | 
             
            # API Reference
         | 
| 102 107 |  | 
| @@ -35,8 +35,12 @@ module ProMotion | |
| 35 35 | 
             
                alias_method :set_nav_bar_right_button, :set_nav_bar_left_button
         | 
| 36 36 |  | 
| 37 37 | 
             
                def set_toolbar_items(buttons = [], animated = true)
         | 
| 38 | 
            -
                   | 
| 39 | 
            -
             | 
| 38 | 
            +
                  if buttons
         | 
| 39 | 
            +
                    self.toolbarItems = Array(buttons).map{|b| b.is_a?(UIBarButtonItem) ? b : create_toolbar_button(b) }
         | 
| 40 | 
            +
                    navigationController.setToolbarHidden(false, animated:animated)
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    navigationController.setToolbarHidden(true, animated:animated)
         | 
| 43 | 
            +
                  end
         | 
| 40 44 | 
             
                end
         | 
| 41 45 | 
             
                alias_method :set_toolbar_buttons, :set_toolbar_items
         | 
| 42 46 | 
             
                alias_method :set_toolbar_button,  :set_toolbar_items
         | 
| @@ -33,6 +33,27 @@ module ProMotion | |
| 33 33 | 
             
                  end
         | 
| 34 34 | 
             
                end
         | 
| 35 35 |  | 
| 36 | 
            +
                def resolve_status_bar
         | 
| 37 | 
            +
                  case self.class.status_bar_type
         | 
| 38 | 
            +
                  when :none
         | 
| 39 | 
            +
                    status_bar_hidden true
         | 
| 40 | 
            +
                  when :light
         | 
| 41 | 
            +
                    status_bar_hidden false
         | 
| 42 | 
            +
                    status_bar_style UIStatusBarStyleLightContent
         | 
| 43 | 
            +
                  else
         | 
| 44 | 
            +
                    status_bar_hidden false
         | 
| 45 | 
            +
                    status_bar_style UIStatusBarStyleDefault
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def status_bar_hidden(hidden)
         | 
| 50 | 
            +
                  UIApplication.sharedApplication.setStatusBarHidden(hidden, withAnimation:self.class.status_bar_animation)
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                def status_bar_style(style)
         | 
| 54 | 
            +
                  UIApplication.sharedApplication.setStatusBarStyle(style)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 36 57 | 
             
                def parent_screen=(parent)
         | 
| 37 58 | 
             
                  @parent_screen = WeakRef.new(parent)
         | 
| 38 59 | 
             
                end
         | 
| @@ -46,6 +67,7 @@ module ProMotion | |
| 46 67 | 
             
                end
         | 
| 47 68 |  | 
| 48 69 | 
             
                def view_will_appear(animated)
         | 
| 70 | 
            +
                  resolve_status_bar
         | 
| 49 71 | 
             
                  self.will_appear
         | 
| 50 72 |  | 
| 51 73 | 
             
                  self.will_present if isMovingToParentViewController
         | 
| @@ -191,6 +213,22 @@ module ProMotion | |
| 191 213 | 
             
                    @title = t
         | 
| 192 214 | 
             
                    @title_type = :view
         | 
| 193 215 | 
             
                  end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                  def status_bar(style=nil, args={})
         | 
| 218 | 
            +
                    if NSBundle.mainBundle.objectForInfoDictionaryKey('UIViewControllerBasedStatusBarAppearance').nil?
         | 
| 219 | 
            +
                      PM.logger.warn("status_bar will have no effect unless you set 'UIViewControllerBasedStatusBarAppearance' to false in your info.plist")
         | 
| 220 | 
            +
                    end
         | 
| 221 | 
            +
                    @status_bar_style = style
         | 
| 222 | 
            +
                    @status_bar_animation = args[:animation] if args[:animation]
         | 
| 223 | 
            +
                  end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                  def status_bar_type
         | 
| 226 | 
            +
                    @status_bar_style || :default
         | 
| 227 | 
            +
                  end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                  def status_bar_animation
         | 
| 230 | 
            +
                    @status_bar_animation || UIStatusBarAnimationSlide
         | 
| 231 | 
            +
                  end
         | 
| 194 232 | 
             
                end
         | 
| 195 233 |  | 
| 196 234 | 
             
                def self.included(base)
         | 
| @@ -3,11 +3,12 @@ module ProMotion | |
| 3 3 | 
             
                def set_attributes(element, args = {})
         | 
| 4 4 | 
             
                  args = get_attributes_from_symbol(args)
         | 
| 5 5 | 
             
                  args.each { |k, v| set_attribute(element, k, v) }
         | 
| 6 | 
            +
                  element.send(:on_styled) if element.respond_to?(:on_styled)
         | 
| 6 7 | 
             
                  element
         | 
| 7 8 | 
             
                end
         | 
| 8 9 |  | 
| 9 10 | 
             
                def set_attribute(element, k, v)
         | 
| 10 | 
            -
                  return  | 
| 11 | 
            +
                  return unless element
         | 
| 11 12 |  | 
| 12 13 | 
             
                  if !element.is_a?(CALayer) && v.is_a?(Hash) && element.respond_to?("#{k}=")
         | 
| 13 14 | 
             
                    element.send("#{k}=", v)
         | 
| @@ -71,6 +72,7 @@ module ProMotion | |
| 71 72 | 
             
                  Array(elements).each do |element|
         | 
| 72 73 | 
             
                    parent_element.addSubview element
         | 
| 73 74 | 
             
                    set_attributes(element, attrs) if attrs && attrs.length > 0
         | 
| 75 | 
            +
                    element.send(:on_load) if element.respond_to?(:on_load)
         | 
| 74 76 | 
             
                  end
         | 
| 75 77 | 
             
                  elements
         | 
| 76 78 | 
             
                end
         | 
| @@ -23,7 +23,7 @@ module ProMotion | |
| 23 23 |  | 
| 24 24 | 
             
                # TODO: Remove this in ProMotion 2.1. Just for migration purposes.
         | 
| 25 25 | 
             
                def check_deprecated_styles
         | 
| 26 | 
            -
                  whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :search_text, :keep_selection, :height, :accessory_type, :style, :properties ]
         | 
| 26 | 
            +
                  whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :moveable, :search_text, :keep_selection, :height, :accessory_type, :style, :properties ]
         | 
| 27 27 | 
             
                  if (data_cell.keys - whitelist).length > 0
         | 
| 28 28 | 
             
                    PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `properties:` hash. See TableScreen documentation.")
         | 
| 29 29 | 
             
                  end
         | 
| @@ -35,6 +35,10 @@ module ProMotion | |
| 35 35 | 
             
                  table_section[:cells].delete_at(params[:index].to_i)
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            +
                def move_cell(from, to)
         | 
| 39 | 
            +
                  section(to.section)[:cells].insert(to.row, section(from.section)[:cells].delete_at(from.row))
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 38 42 | 
             
                def search(search_string)
         | 
| 39 43 | 
             
                  start_searching(search_string)
         | 
| 40 44 |  | 
| @@ -19,6 +19,9 @@ module ProMotion | |
| 19 19 | 
             
                    return unless @refresh_control
         | 
| 20 20 |  | 
| 21 21 | 
             
                    @refresh_control.beginRefreshing
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    # Scrolls the table down to show the refresh control when invoked programatically
         | 
| 24 | 
            +
                    table_view.setContentOffset(CGPointMake(0, table_view.contentOffset.y-@refresh_control.frame.size.height), animated:true) if table_view.contentOffset.y > -65.0
         | 
| 22 25 | 
             
                  end
         | 
| 23 26 | 
             
                  alias :begin_refreshing :start_refreshing
         | 
| 24 27 |  | 
| @@ -15,9 +15,11 @@ module ProMotion | |
| 15 15 |  | 
| 16 16 | 
             
                def screen_setup
         | 
| 17 17 | 
             
                  check_table_data
         | 
| 18 | 
            +
                  set_up_header_view
         | 
| 18 19 | 
             
                  set_up_searchable
         | 
| 19 20 | 
             
                  set_up_refreshable
         | 
| 20 21 | 
             
                  set_up_longpressable
         | 
| 22 | 
            +
                  set_up_row_height
         | 
| 21 23 | 
             
                end
         | 
| 22 24 |  | 
| 23 25 | 
             
                def check_table_data
         | 
| @@ -28,6 +30,17 @@ module ProMotion | |
| 28 30 | 
             
                  @promotion_table_data ||= TableData.new(table_data, table_view)
         | 
| 29 31 | 
             
                end
         | 
| 30 32 |  | 
| 33 | 
            +
                def set_up_header_view
         | 
| 34 | 
            +
                  if self.respond_to?(:table_header_view)
         | 
| 35 | 
            +
                    header_view = self.table_header_view
         | 
| 36 | 
            +
                    if header_view.is_a? UIView
         | 
| 37 | 
            +
                      self.tableView.tableHeaderView = header_view
         | 
| 38 | 
            +
                    else
         | 
| 39 | 
            +
                      PM.logger.warn "Table header views must be a UIView."
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 31 44 | 
             
                def set_up_searchable
         | 
| 32 45 | 
             
                  if self.class.respond_to?(:get_searchable) && self.class.get_searchable
         | 
| 33 46 | 
             
                    self.make_searchable(content_controller: self, search_bar: self.class.get_searchable_params)
         | 
| @@ -50,6 +63,13 @@ module ProMotion | |
| 50 63 | 
             
                  end
         | 
| 51 64 | 
             
                end
         | 
| 52 65 |  | 
| 66 | 
            +
                def set_up_row_height
         | 
| 67 | 
            +
                  if self.class.respond_to?(:get_row_height) && params = self.class.get_row_height
         | 
| 68 | 
            +
                    self.view.rowHeight = params[:height]
         | 
| 69 | 
            +
                    self.view.estimatedRowHeight = params[:estimated]
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 53 73 | 
             
                def searching?
         | 
| 54 74 | 
             
                  self.promotion_table_data.filtered
         | 
| 55 75 | 
             
                end
         | 
| @@ -78,7 +98,6 @@ module ProMotion | |
| 78 98 |  | 
| 79 99 | 
             
                def trigger_action(action, arguments, index_path)
         | 
| 80 100 | 
             
                  return PM.logger.info "Action not implemented: #{action.to_s}" unless self.respond_to?(action)
         | 
| 81 | 
            -
             | 
| 82 101 | 
             
                  case self.method(action).arity
         | 
| 83 102 | 
             
                  when 0 then self.send(action) # Just call the method
         | 
| 84 103 | 
             
                  when 2 then self.send(action, arguments, index_path) # Send arguments and index path
         | 
| @@ -111,22 +130,17 @@ module ProMotion | |
| 111 130 | 
             
                  table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation: map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
         | 
| 112 131 | 
             
                end
         | 
| 113 132 |  | 
| 114 | 
            -
                def table_view_cell(params={})
         | 
| 115 | 
            -
                  params = index_path_to_section_index(params)
         | 
| 116 | 
            -
                  data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
         | 
| 117 | 
            -
                  return UITableViewCell.alloc.init unless data_cell
         | 
| 118 | 
            -
                  create_table_cell(data_cell)
         | 
| 119 | 
            -
                end
         | 
| 120 | 
            -
             | 
| 121 133 | 
             
                def create_table_cell(data_cell)
         | 
| 134 | 
            +
                  new_cell = nil
         | 
| 122 135 | 
             
                  table_cell = table_view.dequeueReusableCellWithIdentifier(data_cell[:cell_identifier]) || begin
         | 
| 123 | 
            -
                     | 
| 124 | 
            -
                     | 
| 125 | 
            -
                     | 
| 126 | 
            -
                     | 
| 127 | 
            -
                     | 
| 136 | 
            +
                    new_cell = data_cell[:cell_class].alloc.initWithStyle(data_cell[:cell_style], reuseIdentifier:data_cell[:cell_identifier])
         | 
| 137 | 
            +
                    new_cell.extend(PM::TableViewCellModule) unless new_cell.is_a?(PM::TableViewCellModule)
         | 
| 138 | 
            +
                    new_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
         | 
| 139 | 
            +
                    new_cell.clipsToBounds = true # fix for changed default in 7.1
         | 
| 140 | 
            +
                    new_cell.setup(data_cell, self)
         | 
| 141 | 
            +
                    new_cell
         | 
| 128 142 | 
             
                  end
         | 
| 129 | 
            -
                  table_cell. | 
| 143 | 
            +
                  table_cell.send(:on_reuse) if !new_cell && table_cell.respond_to?(:on_reuse)
         | 
| 130 144 | 
             
                  table_cell
         | 
| 131 145 | 
             
                end
         | 
| 132 146 |  | 
| @@ -138,6 +152,21 @@ module ProMotion | |
| 138 152 | 
             
                  self.promotion_table_data.search(search_string) if searching?
         | 
| 139 153 | 
             
                end
         | 
| 140 154 |  | 
| 155 | 
            +
                def toggle_edit_mode(animated = true)
         | 
| 156 | 
            +
                  edit_mode({enabled: !editing?, animated: animated})
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                def edit_mode(args = {})
         | 
| 160 | 
            +
                  args[:enabled] = false if args[:enabled].nil?
         | 
| 161 | 
            +
                  args[:animated] = true if args[:animated].nil?
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  setEditing(args[:enabled], animated:args[:animated])
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                def edit_mode?
         | 
| 167 | 
            +
                  !!isEditing
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 141 170 | 
             
                ########## Cocoa touch methods #################
         | 
| 142 171 | 
             
                def numberOfSectionsInTableView(table_view)
         | 
| 143 172 | 
             
                  self.promotion_table_data.sections.length
         | 
| @@ -161,12 +190,15 @@ module ProMotion | |
| 161 190 | 
             
                end
         | 
| 162 191 |  | 
| 163 192 | 
             
                def tableView(table_view, cellForRowAtIndexPath: index_path)
         | 
| 164 | 
            -
                   | 
| 193 | 
            +
                  params = index_path_to_section_index(index_path: index_path)
         | 
| 194 | 
            +
                  data_cell = self.promotion_table_data.cell(section: params[:section], index: params[:index])
         | 
| 195 | 
            +
                  return UITableViewCell.alloc.init unless data_cell
         | 
| 196 | 
            +
                  create_table_cell(data_cell)
         | 
| 165 197 | 
             
                end
         | 
| 166 198 |  | 
| 167 199 | 
             
                def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
         | 
| 168 200 | 
             
                  data_cell = self.promotion_table_data.cell(index_path: index_path)
         | 
| 169 | 
            -
                   | 
| 201 | 
            +
                  table_cell.setup(data_cell, self) if table_cell.respond_to?(:setup)
         | 
| 170 202 | 
             
                  table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
         | 
| 171 203 | 
             
                  table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
         | 
| 172 204 | 
             
                end
         | 
| @@ -192,6 +224,43 @@ module ProMotion | |
| 192 224 | 
             
                  end
         | 
| 193 225 | 
             
                end
         | 
| 194 226 |  | 
| 227 | 
            +
                def tableView(tableView, canMoveRowAtIndexPath:index_path)
         | 
| 228 | 
            +
                  data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                  if (!data_cell[:moveable].nil? || data_cell[:moveable].is_a?(Symbol)) && data_cell[:moveable] != false
         | 
| 231 | 
            +
                    true
         | 
| 232 | 
            +
                  else
         | 
| 233 | 
            +
                    false
         | 
| 234 | 
            +
                  end
         | 
| 235 | 
            +
                end
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                def tableView(tableView, targetIndexPathForMoveFromRowAtIndexPath:source_index_path, toProposedIndexPath:proposed_destination_index_path)
         | 
| 238 | 
            +
                  data_cell = self.promotion_table_data.cell(index_path: source_index_path, unfiltered: true)
         | 
| 239 | 
            +
             | 
| 240 | 
            +
                  if data_cell[:moveable] == :section && source_index_path.section != proposed_destination_index_path.section
         | 
| 241 | 
            +
                    source_index_path
         | 
| 242 | 
            +
                  else
         | 
| 243 | 
            +
                    proposed_destination_index_path
         | 
| 244 | 
            +
                  end
         | 
| 245 | 
            +
                end
         | 
| 246 | 
            +
             | 
| 247 | 
            +
                def tableView(tableView, moveRowAtIndexPath:from_index_path, toIndexPath:to_index_path)
         | 
| 248 | 
            +
                  self.promotion_table_data.move_cell(from_index_path, to_index_path)
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                  if self.respond_to?("on_cell_moved:")
         | 
| 251 | 
            +
                    args = {
         | 
| 252 | 
            +
                      paths: {
         | 
| 253 | 
            +
                        from: from_index_path,
         | 
| 254 | 
            +
                        to: to_index_path
         | 
| 255 | 
            +
                      },
         | 
| 256 | 
            +
                      cell: self.promotion_table_data.section(to_index_path.section)[:cells][to_index_path.row]
         | 
| 257 | 
            +
                    }
         | 
| 258 | 
            +
                    send(:on_cell_moved, args)
         | 
| 259 | 
            +
                  else
         | 
| 260 | 
            +
                    PM.logger.warn "Implement the on_cell_moved method in your PM::TableScreen to be notified when a user moves a cell."
         | 
| 261 | 
            +
                  end
         | 
| 262 | 
            +
                end
         | 
| 263 | 
            +
             | 
| 195 264 | 
             
                def tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
         | 
| 196 265 | 
             
                  return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
         | 
| 197 266 |  | 
| @@ -255,6 +324,16 @@ module ProMotion | |
| 255 324 | 
             
                    UITableViewStylePlain
         | 
| 256 325 | 
             
                  end
         | 
| 257 326 |  | 
| 327 | 
            +
                  def row_height(height, args={})
         | 
| 328 | 
            +
                    height = UITableViewAutomaticDimension if height == :auto
         | 
| 329 | 
            +
                    args[:estimated] ||= height unless height == UITableViewAutomaticDimension
         | 
| 330 | 
            +
                    @row_height = { height: height, estimated: args[:estimated] || 44.0 }
         | 
| 331 | 
            +
                  end
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                  def get_row_height
         | 
| 334 | 
            +
                    @row_height ||= nil
         | 
| 335 | 
            +
                  end
         | 
| 336 | 
            +
             | 
| 258 337 | 
             
                  # Searchable
         | 
| 259 338 | 
             
                  def searchable(params={})
         | 
| 260 339 | 
             
                    @searchable_params = params
         | 
    
        data/lib/ProMotion/version.rb
    CHANGED
    
    
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            describe "ProMotion::TableScreen functionality" do
         | 
| 2 | 
            +
              tests PM::TestMiniTableScreen
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              def table_screen
         | 
| 5 | 
            +
                @table_screen ||= begin
         | 
| 6 | 
            +
                  t = TestMiniTableScreen.new(nav_bar: true)
         | 
| 7 | 
            +
                  t
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def controller
         | 
| 12 | 
            +
                table_screen.navigationController
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              before do
         | 
| 16 | 
            +
                UIView.setAnimationsEnabled false
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              after do
         | 
| 20 | 
            +
                @table_screen = nil
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it "no cells have fired on_reuse before scrolling" do
         | 
| 24 | 
            +
                ip = NSIndexPath.indexPathForRow(0, inSection: 0)
         | 
| 25 | 
            +
                cell = table_screen.tableView(table_screen.table_view, cellForRowAtIndexPath: ip)
         | 
| 26 | 
            +
                cell.on_reuse_fired.should.not == true
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              it "cell has fired on_reuse after scrolling" do
         | 
| 30 | 
            +
                ip = NSIndexPath.indexPathForRow(10, inSection: 0)
         | 
| 31 | 
            +
                table_screen.tableView.scrollToRowAtIndexPath(ip, atScrollPosition: UITableViewScrollPositionTop, animated: false)
         | 
| 32 | 
            +
                wait 0.001 do
         | 
| 33 | 
            +
                  ip = NSIndexPath.indexPathForRow(0, inSection: 0)
         | 
| 34 | 
            +
                  table_screen.tableView.scrollToRowAtIndexPath(ip, atScrollPosition: UITableViewScrollPositionTop, animated: false)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  cell = views(TestCell).first
         | 
| 37 | 
            +
                  cell.on_reuse_fired.should == true
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
             | 
| 44 | 
            +
             | 
| @@ -70,7 +70,7 @@ describe "ProMotion::TableScreen functionality" do | |
| 70 70 | 
             
              it "should use editing_style to delete the table row" do
         | 
| 71 71 | 
             
                table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
         | 
| 72 72 | 
             
                table_screen.cell_was_deleted.should != true
         | 
| 73 | 
            -
                flick("Just another deletable blank row", : | 
| 73 | 
            +
                flick("Just another deletable blank row", to: :left)
         | 
| 74 74 |  | 
| 75 75 | 
             
                wait 0.11 do
         | 
| 76 76 | 
             
                  # Tap the delete button
         | 
| @@ -89,7 +89,7 @@ describe "ProMotion::TableScreen functionality" do | |
| 89 89 | 
             
              it "should not allow deleting if on_cell_delete returns `false`" do
         | 
| 90 90 | 
             
                table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
         | 
| 91 91 | 
             
                table_screen.cell_was_deleted.should != true
         | 
| 92 | 
            -
                flick("A non-deletable blank row", : | 
| 92 | 
            +
                flick("A non-deletable blank row", to: :left)
         | 
| 93 93 |  | 
| 94 94 | 
             
                wait 0.11 do
         | 
| 95 95 | 
             
                  # Tap the delete button
         | 
    
        data/spec/unit/screen_spec.rb
    CHANGED
    
    | @@ -26,6 +26,25 @@ describe "screen properties" do | |
| 26 26 | 
             
                HomeScreen.title.should != 'instance method'
         | 
| 27 27 | 
             
              end
         | 
| 28 28 |  | 
| 29 | 
            +
              it "should have a default UIStatusBar style" do
         | 
| 30 | 
            +
                @screen.view_will_appear(false)
         | 
| 31 | 
            +
                UIApplication.sharedApplication.isStatusBarHidden.should == false
         | 
| 32 | 
            +
                UIApplication.sharedApplication.statusBarStyle.should == UIStatusBarStyleDefault
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              it "should set the UIStatusBar style to :none" do
         | 
| 36 | 
            +
                @screen.class.status_bar :none
         | 
| 37 | 
            +
                @screen.view_will_appear(false)
         | 
| 38 | 
            +
                UIApplication.sharedApplication.isStatusBarHidden.should == true
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              it "should set the UIStatusBar style to :light" do
         | 
| 42 | 
            +
                @screen.class.status_bar :light
         | 
| 43 | 
            +
                @screen.view_will_appear(false)
         | 
| 44 | 
            +
                UIApplication.sharedApplication.isStatusBarHidden.should == false
         | 
| 45 | 
            +
                UIApplication.sharedApplication.statusBarStyle.should == UIStatusBarStyleLightContent
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 29 48 | 
             
              it "should set the tab bar item with a system item" do
         | 
| 30 49 | 
             
                @screen.set_tab_bar_item system_item: :contacts
         | 
| 31 50 | 
             
                comparison = UITabBarItem.alloc.initWithTabBarSystemItem(UITabBarSystemItemContacts, tag: 0)
         | 
| @@ -267,6 +286,29 @@ describe "screen with toolbar" do | |
| 267 286 | 
             
                screen.navigationController.toolbarHidden?.should == false
         | 
| 268 287 | 
             
              end
         | 
| 269 288 |  | 
| 289 | 
            +
              it "doesn't show the toolbar when passed nil" do
         | 
| 290 | 
            +
                screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
         | 
| 291 | 
            +
                screen.on_load
         | 
| 292 | 
            +
                screen.set_toolbar_button(nil, false)
         | 
| 293 | 
            +
                screen.navigationController.toolbarHidden?.should == true
         | 
| 294 | 
            +
              end
         | 
| 295 | 
            +
             | 
| 296 | 
            +
              it "doesn't show the toolbar when passed false" do
         | 
| 297 | 
            +
                screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
         | 
| 298 | 
            +
                screen.on_load
         | 
| 299 | 
            +
                screen.set_toolbar_button(false, false)
         | 
| 300 | 
            +
                screen.navigationController.toolbarHidden?.should == true
         | 
| 301 | 
            +
              end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
              it "hides the toolbar when passed nil" do
         | 
| 304 | 
            +
                screen = HomeScreen.new modal: true, nav_bar: true, toolbar: true
         | 
| 305 | 
            +
                screen.on_load
         | 
| 306 | 
            +
                screen.set_toolbar_button([{title: "Testing Toolbar"}], false)
         | 
| 307 | 
            +
                screen.navigationController.toolbarHidden?.should == false
         | 
| 308 | 
            +
                screen.set_toolbar_button(nil, false)
         | 
| 309 | 
            +
                screen.navigationController.toolbarHidden?.should == true
         | 
| 310 | 
            +
              end
         | 
| 311 | 
            +
             | 
| 270 312 | 
             
            end
         | 
| 271 313 |  | 
| 272 314 | 
             
            describe 'toolbar tinted buttons' do
         | 
| @@ -172,6 +172,10 @@ describe "PM::Table module" do | |
| 172 172 | 
             
                cell.backgroundColor.should == UIColor.blueColor
         | 
| 173 173 | 
             
              end
         | 
| 174 174 |  | 
| 175 | 
            +
              it "should have a header view" do
         | 
| 176 | 
            +
                @subject.tableView.tableHeaderView.class.should == UIImageView
         | 
| 177 | 
            +
              end
         | 
| 178 | 
            +
             | 
| 175 179 | 
             
              describe("section with custom title_view") do
         | 
| 176 180 |  | 
| 177 181 | 
             
                it "should use the correct class for section view" do
         | 
| @@ -50,6 +50,18 @@ describe "table screens" do | |
| 50 50 | 
             
                  end
         | 
| 51 51 | 
             
                end
         | 
| 52 52 |  | 
| 53 | 
            +
                it "sets the auto row height and estimated row height properly" do
         | 
| 54 | 
            +
                  @screen.view.rowHeight.should == UITableViewAutomaticDimension
         | 
| 55 | 
            +
                  @screen.view.estimatedRowHeight.should == 97
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it "sets the fixed row height properly" do
         | 
| 59 | 
            +
                  screen = UpdateTestTableScreen.new
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  screen.view.rowHeight.should == 77
         | 
| 62 | 
            +
                  screen.view.estimatedRowHeight.should == 77
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 53 65 | 
             
              end
         | 
| 54 66 |  | 
| 55 67 | 
             
              describe "search functionality" do
         | 
| @@ -126,5 +138,103 @@ describe "table screens" do | |
| 126 138 |  | 
| 127 139 | 
             
              end
         | 
| 128 140 |  | 
| 141 | 
            +
              describe "test PM::TableScreen's moving cells functionality" do
         | 
| 142 | 
            +
                before do
         | 
| 143 | 
            +
                  UIView.animationsEnabled = false
         | 
| 144 | 
            +
                  @screen = TestTableScreen.new
         | 
| 145 | 
            +
                  @screen.on_load
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                it "should allow the table screen to enter editing mode" do
         | 
| 149 | 
            +
                  @screen.isEditing.should == false
         | 
| 150 | 
            +
                  @screen.edit_mode(enabled:true, animated:false)
         | 
| 151 | 
            +
                  @screen.isEditing.should == true
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                it "should use a convenience method to see if the table is editing" do
         | 
| 155 | 
            +
                  @screen.isEditing.should == @screen.edit_mode?
         | 
| 156 | 
            +
                  @screen.edit_mode(enabled:true, animated:false)
         | 
| 157 | 
            +
                  @screen.isEditing.should == @screen.edit_mode?
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                it "should toggle editing mode" do
         | 
| 161 | 
            +
                  @screen.edit_mode?.should == false
         | 
| 162 | 
            +
                  @screen.toggle_edit_mode(false)
         | 
| 163 | 
            +
                  @screen.edit_mode?.should == true
         | 
| 164 | 
            +
                  @screen.toggle_edit_mode(false)
         | 
| 165 | 
            +
                  @screen.edit_mode?.should == false
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                it "should return true for cells that are moveable" do
         | 
| 169 | 
            +
                  # Index path with :moveable = true
         | 
| 170 | 
            +
                  index_path = NSIndexPath.indexPathForRow(0, inSection:4)
         | 
| 171 | 
            +
                  @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == true
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                  # Index path with no :moveable set
         | 
| 174 | 
            +
                  index_path = NSIndexPath.indexPathForRow(2, inSection:4)
         | 
| 175 | 
            +
                  @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == false
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                  # Index path with :moveable = false
         | 
| 178 | 
            +
                  index_path = NSIndexPath.indexPathForRow(4, inSection:4)
         | 
| 179 | 
            +
                  @screen.tableView(@screen.tableView, canMoveRowAtIndexPath: index_path).should == false
         | 
| 180 | 
            +
                end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
                it "should rearrange the data object when a cell is moved" do
         | 
| 183 | 
            +
                  move_from = NSIndexPath.indexPathForRow(0, inSection:4)
         | 
| 184 | 
            +
                  move_to   = NSIndexPath.indexPathForRow(2, inSection:4)
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                  @screen.promotion_table_data.section(4)[:cells].map{|c| c[:title]}.should == [
         | 
| 187 | 
            +
                    'Cell 1',
         | 
| 188 | 
            +
                    'Cell 2',
         | 
| 189 | 
            +
                    'Cell 3',
         | 
| 190 | 
            +
                    'Cell 4',
         | 
| 191 | 
            +
                    'Cell 5'
         | 
| 192 | 
            +
                  ]
         | 
| 193 | 
            +
                  @screen.tableView(@screen.tableView, moveRowAtIndexPath:move_from, toIndexPath:move_to)
         | 
| 194 | 
            +
                  @screen.promotion_table_data.section(4)[:cells].map{|c| c[:title]}.should == [
         | 
| 195 | 
            +
                    'Cell 2',
         | 
| 196 | 
            +
                    'Cell 3',
         | 
| 197 | 
            +
                    'Cell 1',
         | 
| 198 | 
            +
                    'Cell 4',
         | 
| 199 | 
            +
                    'Cell 5'
         | 
| 200 | 
            +
                  ]
         | 
| 201 | 
            +
                end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                it "should call :cell_moved when moving a cell" do
         | 
| 204 | 
            +
                  move_from = NSIndexPath.indexPathForRow(0, inSection:4)
         | 
| 205 | 
            +
                  move_to   = NSIndexPath.indexPathForRow(2, inSection:4)
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                  @screen.cell_was_moved.nil?.should == true
         | 
| 208 | 
            +
                  @screen.tableView(@screen.tableView, moveRowAtIndexPath:move_from, toIndexPath:move_to)
         | 
| 209 | 
            +
                  @screen.cell_was_moved.is_a?(Hash).should == true
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                  cell = @screen.cell_was_moved
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                  cell[:paths][:from].should == move_from
         | 
| 214 | 
            +
                  cell[:paths][:to].should == move_to
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                  cell[:cell][:title].should == "Cell 1"
         | 
| 217 | 
            +
                end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                it "should allow cells to move to other sections" do
         | 
| 220 | 
            +
                  move_from = NSIndexPath.indexPathForRow(1, inSection:4)
         | 
| 221 | 
            +
                  move_to   = NSIndexPath.indexPathForRow(0, inSection:3)
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                  moving_to = @screen.tableView(@screen.tableView, targetIndexPathForMoveFromRowAtIndexPath:move_from, toProposedIndexPath:move_to)
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                  moving_to.should == move_to
         | 
| 226 | 
            +
                end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
                it "should not allow cells to move to other sections" do
         | 
| 229 | 
            +
                  move_from = NSIndexPath.indexPathForRow(0, inSection:4)
         | 
| 230 | 
            +
                  move_to   = NSIndexPath.indexPathForRow(0, inSection:3)
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                  moving_to = @screen.tableView(@screen.tableView, targetIndexPathForMoveFromRowAtIndexPath:move_from, toProposedIndexPath:move_to)
         | 
| 233 | 
            +
             | 
| 234 | 
            +
                  moving_to.should == move_from
         | 
| 235 | 
            +
                end
         | 
| 236 | 
            +
             | 
| 237 | 
            +
              end
         | 
| 238 | 
            +
             | 
| 129 239 | 
             
            end
         | 
| 130 240 |  | 
| @@ -1,3 +1,16 @@ | |
| 1 | 
            +
            class TestView < UIView
         | 
| 2 | 
            +
              attr_accessor :on_load_fired
         | 
| 3 | 
            +
              attr_accessor :on_styled_fired
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def on_load
         | 
| 6 | 
            +
                self.on_load_fired = true
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def on_styled
         | 
| 10 | 
            +
                self.on_styled_fired = true
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 1 14 | 
             
            describe "view helpers" do
         | 
| 2 15 |  | 
| 3 16 | 
             
              def equal_rect(rect)
         | 
| @@ -61,6 +74,18 @@ describe "view helpers" do | |
| 61 74 | 
             
                layered_view.layer.backgroundColor.should == UIColor.redColor.CGColor
         | 
| 62 75 | 
             
              end
         | 
| 63 76 |  | 
| 77 | 
            +
              it "should trigger on_load on a view that supports it" do
         | 
| 78 | 
            +
                v = TestView.new
         | 
| 79 | 
            +
                @dummy.add v
         | 
| 80 | 
            +
                v.on_load_fired.should == true
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              it "should trigger on_styled on a view that supports it" do
         | 
| 84 | 
            +
                v = TestView.new
         | 
| 85 | 
            +
                @dummy.set_attributes v, { background_color: UIColor.blueColor }
         | 
| 86 | 
            +
                v.on_styled_fired.should == true
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 64 89 |  | 
| 65 90 | 
             
              context "content sizing" do
         | 
| 66 91 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: ProMotion
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Jamon Holmgren
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2014- | 
| 13 | 
            +
            date: 2014-12-05 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: methadone
         | 
| @@ -133,6 +133,7 @@ files: | |
| 133 133 | 
             
            - lib/ProMotion/web/web_screen_module.rb
         | 
| 134 134 | 
             
            - spec/functional/func_screen_spec.rb
         | 
| 135 135 | 
             
            - spec/functional/func_split_screen_spec.rb
         | 
| 136 | 
            +
            - spec/functional/func_table_screen_cell_spec.rb
         | 
| 136 137 | 
             
            - spec/functional/func_table_screen_spec.rb
         | 
| 137 138 | 
             
            - spec/functional/func_table_screen_updating_spec.rb
         | 
| 138 139 | 
             
            - spec/functional/func_web_screen_spec.rb
         | 
| @@ -191,6 +192,7 @@ summary: ProMotion is a fast way to get started building RubyMotion apps. Instea | |
| 191 192 | 
             
            test_files:
         | 
| 192 193 | 
             
            - spec/functional/func_screen_spec.rb
         | 
| 193 194 | 
             
            - spec/functional/func_split_screen_spec.rb
         | 
| 195 | 
            +
            - spec/functional/func_table_screen_cell_spec.rb
         | 
| 194 196 | 
             
            - spec/functional/func_table_screen_spec.rb
         | 
| 195 197 | 
             
            - spec/functional/func_table_screen_updating_spec.rb
         | 
| 196 198 | 
             
            - spec/functional/func_web_screen_spec.rb
         |