Giter Club home page Giter Club logo

promotion's Issues

Change name of PM::AppDelegateParent to PM::Delegate

I've never been fond of ProMotion::AppDelegateParent. What say we change it to just ProMotion::Delegate?

class AppDelegate < ProMotion::Delegate
  def on_load(app, options)
    open HomeScreen
  end
end

I'll keep the AppDelegateParent active so older apps can use it.

ProMotion template

Now that RubyMotion 2.0 has template support, I'd like to build a ProMotion template.

Project Templates

RubyMotion now exposes functionality to let users chose a template when creating a new project, by passing a value to the —template argument of the motion create command.

RubyMotion comes with 3 builtin templates: ios (the default one), osx and gem, which will respectively create a RubyMotion iOS, OSX or RubyGem project.

For example, to create a new OSX project named Hello:

$ motion create --template=osx Hello
Create Hello
Create Hello/app/app_delegate.rb
Create Hello/app/menu.rb
Create Hello/Rakefile
Create Hello/resources/Credits.rtf
Create Hello/spec/main_spec.rb
3rd-party templates can also be installed into the ~/Library/RubyMotion/template directory.

We expect certain RubyMotion gems to make use of the system to provide richer project templates that include specific integration code. As an example, the Joybox team is looking into making a template that includes a game skeletton.

Title not being set.

When including ProMotion functionality, the class method title doesn't appear to work.

The following code does not set the title.

class SomeScreen < UIViewController
  include PM::ScreenModule
  title "Some Screen's Title"
end

Whereas, this does:

class OtherScreen < PM::Screen
  title "Other Screen Title"
end

And this too:

class SomeScreen < UIViewController
  include PM::ScreenModule

  def on_load
    self.title = "Some Screen's Title"
  end
end

CamelCase options in sectioned_table.rb

    def tableView(table_view, cellForRowAtIndexPath:indexPath)
      # Aah, magic happens here...

      data_cell = cell_at_section_and_index(indexPath.section, indexPath.row)
      return UITableViewCell.alloc.init unless data_cell
      data_cell[:cellStyle] ||= UITableViewCellStyleDefault
      data_cell[:cellIdentifier] ||= "Cell"
      cellIdentifier = data_cell[:cellIdentifier]
      data_cell[:cellClass] ||= ProMotion::TableViewCell

      table_cell = table_view.dequeueReusableCellWithIdentifier(cellIdentifier)
      unless table_cell
        table_cell = data_cell[:cellClass].alloc.initWithStyle(data_cell[:cellStyle], reuseIdentifier:cellIdentifier)

        # Add optimizations here
        table_cell.layer.masksToBounds = true if data_cell[:masksToBounds]
        table_cell.backgroundColor = data_cell[:backgroundColor] if data_cell[:backgroundColor]
        table_cell.selectionStyle = data_cell[:selectionStyle] if data_cell[:selectionStyle]
        table_cell.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin
      end

      if data_cell[:cellClassAttributes]
        set_cell_attributes table_cell, data_cell[:cellClassAttributes]
      end

      if data_cell[:accessoryView]
        table_cell.accessoryView = data_cell[:accessoryView]
        table_cell.accessoryView.autoresizingMask = UIViewAutoresizingFlexibleWidth
      end

      if data_cell[:accessoryType]
        tableCell.accessoryType = data_cell[:accessoryType]
      end

      if data_cell[:accessory] && data_cell[:accessory] == :switch
        switchView = UISwitch.alloc.initWithFrame(CGRectZero)
        switchView.addTarget(self, action: "accessory_toggled_switch:", forControlEvents:UIControlEventValueChanged);
        switchView.on = true if data_cell[:accessoryDefault]
        table_cell.accessoryView = switchView
      end

      if data_cell[:subtitle]
        table_cell.detailTextLabel.text = data_cell[:subtitle]
        table_cell.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth
      end

      table_cell.selectionStyle = UITableViewCellSelectionStyleNone if data_cell[:no_select]

      if data_cell[:remoteImage]
        if table_cell.imageView.respond_to?("setImageWithURL:placeholderImage:")
          url = data_cell[:remoteImage][:url]
          url = NSURL.URLWithString(url) unless url.is_a?(NSURL)
          placeholder = data_cell[:remoteImage][:placeholder]
          placeholder = UIImage.imageNamed(placeholder) if placeholder.is_a?(String)

          table_cell.image_size = data_cell[:remoteImage][:size] if data_cell[:remoteImage][:size] && table_cell.respond_to?("image_size=")
          table_cell.imageView.setImageWithURL(url, placeholderImage: placeholder)
          table_cell.imageView.layer.masksToBounds = true
          table_cell.imageView.layer.cornerRadius = data_cell[:remoteImage][:radius]
        else
          ProMotion::Console.log("ProMotion Warning: to use remoteImage with TableScreen you need to include the CocoaPod 'SDWebImage'.", with_color: ProMotion::Console::RED_COLOR)
        end
      elsif data_cell[:image]
        table_cell.imageView.layer.masksToBounds = true
        table_cell.imageView.image = data_cell[:image][:image]
        table_cell.imageView.layer.cornerRadius = data_cell[:image][:radius] if data_cell[:image][:radius]
      end

      if data_cell[:subViews]
        tag_number = 0
        data_cell[:subViews].each do |view|
          # Remove an existing view at that tag number
          tag_number += 1
          existing_view = table_cell.viewWithTag(tag_number)
          existing_view.removeFromSuperview if existing_view

          # Add the subview if it exists
          if view
            view.tag = tag_number
            table_cell.addSubview view
          end
        end
      end

      if data_cell[:details]
        table_cell.addSubview data_cell[:details][:image]
      end

      if data_cell[:styles] && data_cell[:styles][:textLabel] && data_cell[:styles][:textLabel][:frame]
        ui_label = false
        table_cell.contentView.subviews.each do |view|
          if view.is_a? UILabel
            ui_label = true
            view.text = data_cell[:styles][:textLabel][:text]
          end
        end

        unless ui_label == true
          label ||= UILabel.alloc.initWithFrame(CGRectZero)
          set_cell_attributes label, data_cell[:styles][:textLabel]
          table_cell.contentView.addSubview label
        end
        # hackery
        table_cell.textLabel.textColor = UIColor.clearColor
      else
        cell_title = data_cell[:title]
        cell_title ||= ""
        table_cell.textLabel.text = cell_title
      end

      return table_cell
    end

TableScreen BackgroundColor stays white

The code below produces an all white tableview.

class MenuScreen < ProMotion::TableScreen
  title "Menu"

  def on_load
    # tried both of these
    self.view.backgroundColor = UIColor.darkGrayColor
    self.tableView.backgroundColor = UIColor.darkGrayColor
  end

  def table_data
    [{
      title: "Account",
      cells: [
        { title: "Edit Profile", action: :edit_profile, arguments: { id: 3 }, background_color: UIColor.darkGrayColor },
        { title: "Log Out", action: :log_out },
        { title: "Notification Settings", action: :notification_settings }
      ]
    }]
  end

Add Test Coverage

I think before you get too many more versions under your belt, that we should look at adding some test coverage to the suite. Would have definitely helped with the refactoring that went on from 0.3 => 0.4 => 0.5

I'd love to help out, so if you want to get started over Twitter & share some contact info, let's make this happen. I added test coverage to my (much smaller) gem for RM that I released yesterday, can_i, and it was actually a pleasure to do and not terribly difficult to get started.

There's articles on using cucumber with some other library, and even a gem for mocking with RM.

Pull to refresh in Table Screen

It could be great to have a simple config to make a pull refresh enabled for a table view.
Imagine if the data came from a json call or whatever, you can call the update_table_data.

We can use the UIRefreshControl for iOS 6 and use CKRefreshControl for older version : we can use the same code for iOS 5 and 6 with that.

It could be somethings like :

class SettingsScreen < ProMotion::TableScreen
  title "Settings"
  pullToRefresh true

  def on_load
    add_right_nav_button(label: "Save", action: :save)
    set_tab_bar_item(title: "Settings", icon: "settings.png")
  end

  def table_data
    ...
  end
end

What do you think about that ?

How to open a modal and nav_bar screen?

I want to open a new modal screen with:

open TestScreen.new, {modal: true, nav_bar: true}

But I get always the error message:

2013-03-08 14:01:41.255 Inventory[75875:c07] screen_navigation.rb:29:in `open_screen:': NSInvalidArgumentException: Application tried to present modally an active controller <DbViewScreen: 0x1d356c70>. (RuntimeError)
    from db_view_screen.rb:27:in `add_item'

What I doing wrong?

ProMotion installation generator

I'd like to make the installation instructions simpler and it would be great to be able to do something like a Rails generator:

$ motion generate promotion:install

...or...

$ rake promotion:install

This could modify the app_delegate.rb, create the app/screens and app/styles folders, etc.

Any ideas on how we could accomplish this? A Rake task seems like the easiest route to take.

Specs fail with RubyMotion 2.0

I've submitted a support request.

With RM 1.35, specs pass fine in ProMotion 0.6 branch:

https://github.com/clearsightstudio/ProMotion/tree/version-0.6

Running rake spec debug=1 -- no problem. "Program exited normally."

With RM 2.0, partway through it crashes with this:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x30b3b0e2
0x004f709b in objc_msgSend ()

If you clone the repo and run rake spec debug=1 with both RM 1.35 and RM 2.0 you'll see this happen. I was able to replicate every time.

I'll update here with any response. For now, downgrading to RubyMotion 1.35 (via sudo motion update --force-version=1.35) works.

table screen w/ searchable - search fails with:

(main)> 2013-05-30 16:05:05.421 mobileAdmin2[6650:c07] _searcha:in searchDisplayController:shouldReloadTableForSearchString:': undefined methodsearch' for true:TrueClass (NoMethodError)
2013-05-30 16:05:05.448 mobileAdmin2[6650:c07] *** Terminating app due to uncaught exception 'NoMethodError', reason: '_searcha:in searchDisplayController:shouldReloadTableForSearchString:': undefined methodsearch' for true:TrueClass (NoMethodError)

Getting Started: Clarification

It's worth mentioning that when a new user drops the on_load code into AppDelegate, they have to remove the boilerplate didFinishLoadingWithOptions method or they'll never get the goodness of ProMotion.

Great work, BTW!

Element styling

I think the element styling needs more work and potentially a new paradigm.

  • ProMotion works well with Pixate but not everyone will have Pixate or want to use it.
  • The add method (previously add_element) works pretty well but still litters your controllers with view code
  • Subclassing views is a fine way to style them, but you end up with a lot of files and not everyone wants to do that
  • Teacup is one way to accomplish this but not everyone likes the way it works

I'd like some ideas. Potential discussion points:

  1. Subclass UIKit elements to add additional functionality to them, much as we've done to the UIController set?
  2. Provide a "stylesheets" folder and do something with that?
  3. Pull in an external styling system I'm not aware of, or integrate better with Teacup?

Of course, we should avoid forcing this styling paradigm on people and still work well with Teacup, Pixate, and other styling DSLs. But I think a built-in or included styling system would be a good idea.

Comments needed!

For TableScreens, on_init is called after table_setup

Note - I've edited the original issue to be more clear.

I've gotten around this by defining my table_data method like this:

attr_accessor :my_attr_accessor

def on_init
  @my_attr_accessor = []
end

def table_data
  on_init if @my_attr_accessor.nil?
  # build table data here
end

It looks like we could just switch these two lines in _screen_module.rb to fix the issue so that there's a chance to initialize things before the table is built:

self.table_setup if self.respond_to?(:table_setup)
self.on_init if self.respond_to?(:on_init)

open doesn't animate when nav_bar: false

Hi, I don't want that nav_bar on my app, but I do want the sliding animation when you open a new screen. Since animated: true only works on modal screens, how to do this?

Something like: [self.navigationController pushViewController:vc animated:YES];

Screens - inherit from UIViewController and add the ProMotion sugar via module

This will allow devs to inherit from any UIViewController and mix in ProMotion capabilities.

class HomeScreen < AnyCustomViewController
  include ProMotion::ScreenModule

  title "Home Screen"

  def will_appear
    @label = add_view UILabel.alloc.initWithFrame(CGRectMake(5, 5, 20, 20)), {
      text: "This is awesome!",
      font: UIFont.UIFont.systemFontOfSize(18)
    }
  end
end

Get the controller of the screen

There's numbers of pods and gems who need the controller of the current view to work.

It could be great to have a function that return the view controller for a screen and the table view controller when it's the case.

RUBYMOTION_ENV uninitialized constant

Since I'm using 0.7 I had a deprecation but the logging of this information created this
error message:

logger.rb:36:in `log:': uninitialized constant ProMotion::Logger::RUBYMOTION_ENV (NameError)
    from logger.rb:46:in `deprecated:'
    from delegate.rb:33:in `inherited:'

Don't work with ::RUBYMOTION_ENV. But "p RUBYMOTION_ENV" in my on_load in app_delegate.rb works. Are there some Gem limitations?

Dismissing SplitView

I need to dismiss the master view in portrait mode when a cell in the master view's table is clicked. I can't see how to do this in the existing code, so I hacked out some code. Before submitting a pull, I wanted to run it by you for comment. In split_screen.rb:

    def dismiss_popover_controller
      @popover_controller.dismissPopoverAnimated(@popover_controller) if @popover_controller
    end

    # UISplitViewControllerDelegate methods

    def splitViewController(svc, willHideViewController: vc, withBarButtonItem: button, forPopoverController: pc)
      button.title = vc.title
      svc.detail_screen.navigationItem.leftBarButtonItem = button;
      @popover_controller = pc
    end

    def splitViewController(svc, willShowViewController: vc, invalidatingBarButtonItem: barButtonItem)
      svc.detail_screen.navigationItem.leftBarButtonItem = nil
      @popover_controller = nil
    end

Add the method dismiss_popover_controller and memoized the popover.

In client code, the split view is created in AppDelegate, so I do this:

      App.delegate.dismiss_popover_controller

Support for UITableView deleteRowsAtIndexPaths

I keep getting:
The number of rows contained in an existing section after the update (77) must be equal to the number of rows contained in that section before the update (77), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted)

Crash with searchable tableview in 0.7-head

I've got a table that works fine in 0.6 and when I tap the search box to begin searching, the app crashes in version-0.7.

The initial table loads correctly and it only crashes if you tap the search field.

(main)> 2013-05-30 12:11:49.693 BA Styles[92849:c07] _table.rb:104:in `tableView:cellForRowAtIndexPath:': undefined method `table_view_cell' for true:TrueClass (NoMethodError)
2013-05-30 12:11:49.694 BA Styles[92849:c07] *** Terminating app due to uncaught exception 'NoMethodError', reason: '_table.rb:104:in `tableView:cellForRowAtIndexPath:': undefined method `table_view_cell' for true:TrueClass (NoMethodError)
'
*** First throw call stack:
(0x1cd8012 0x7bae7e 0x339a44 0x3f52 0x3591)
libc++abi.dylib: terminate called throwing an exception
((null))> rake aborted!
Command failed with status (1): [DYLD_FRAMEWORK_PATH="/Applications/Xcode.a...]
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/file_utils.rb:53:in `block in create_shell_runner'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/file_utils.rb:45:in `call'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/file_utils.rb:45:in `sh'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/file_utils_ext.rb:37:in `sh'
/Library/RubyMotion/lib/motion/project/template/ios.rb:93:in `block in <top (required)>'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `call'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:246:in `block in execute'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `each'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:241:in `execute'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:184:in `block in invoke_with_call_chain'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:205:in `block in invoke_prerequisites'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `each'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:203:in `invoke_prerequisites'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:183:in `block in invoke_with_call_chain'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:177:in `invoke_with_call_chain'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/task.rb:170:in `invoke'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:143:in `invoke_task'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block (2 levels) in top_level'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `each'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:101:in `block in top_level'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:110:in `run_with_threads'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:95:in `top_level'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:73:in `block in run'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:160:in `standard_exception_handling'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon@global/gems/rake-10.0.4/lib/rake/application.rb:70:in `run'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon/bin/ruby_noexec_wrapper:14:in `eval'
/Users/mrickert/.rvm/gems/ruby-1.9.3-p327-falcon/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => default => simulator
(See full trace by running task with --trace)

Dynamic data in GroupedTableScreen

I'm new to Rubymotion, so this question might be naïve.

I'm using GroupedTableScreen, and I have the table items to be pulled from remote server.

 def on_load
   BW::HTTP.get("http://remoteserver.com/api.json") do |response|
      @games_list = massage_data(response)
   end
 end

 def on_load
    @hometable ||= [{
      title: "List of games",
      cells: @games_list
    },
    {
      title: "Settings",
      cells:
        [{
        title: "Account", action: :account_settings
        },
        {
          title: "Notification", action: :notification_settings  
      }]
    }
  ]
 end

Unfortunately, this doesn't work because BW:HTTP is async. How do I update the cell data in GroupedTable?

Having problem with rotation

My app supports all 4 layout rotations but I have a single screen that I want to appear ONLY in portrait.

I understand that the only way to do this is to present the view controller modally (since all UIViewControllers take the rotation property of their UINavigationController). Not a problem.

I'm using the latest version-0.7 head

So i'm invoking the new PM::Screen subclass like this:

  def open_srm_analyzer_screen(args={})
      open SRMAnalyzerScreen.new, {modal:true, nav_bar:true}
  end

And in my class, I'm defining this:

# ...
  def should_rotate(orientation)
    puts "Trying to determine rotation"
    UIDeviceOrientationPortrait == orientation
  end

  def should_autorotate
    puts "should autorotate?"
    false
  end

  def supported_orientations
    puts "checking supported orientations"
    orientations = 0
    orientations |= UIInterfaceOrientationMaskPortrait
    orientations
  end
# ...

...but none of those methods ever get called. There's no output on the REPL when switching orientations in the simulator.

Any help would be appreciated. Am I doing something wrong? Let me know if you'd like any additional information.

Screens - subscribe to events

Let's add an abstraction to NSNotification (perhaps as a separate gem that integrates with ProMotion).

Example:

class SomeScreen < ProMotion::Screen
  def will_appear
    subscribe_to :an_event, action: :handle_an_event
  end
  def handle_an_event
    # handle it
  end
end

# some other class
  broadcast :an_event

Fire on_return in the view_did_disappear method?

There's a problem when dismissing a modal screen and trying to open another one in that on_return is fired as soon as the modal starts animating but before it has a chance to completely disappear. This prevents you from opening another screen (modally or otherwise).

It would be possible to wait for the view_did_disappear to fire before sending the on_return method call. Anybody see any negative side effects?

Crash when using custom accessoryStyle

(main)> 2013-02-21 13:10:54.536 OUCalc[19236:c07] sectioned_table.rb:143:in `tableView:cellForRowAtIndexPath:': undefined local variable or method `tableCell' for #<SearchModulesScreen:0xaa219a0> (NameError)
2013-02-21 13:10:54.538 OUCalc[19236:c07] *** Terminating app due to uncaught exception 'NameError', reason: 'sectioned_table.rb:143:in `tableView:cellForRowAtIndexPath:': undefined local variable or method `tableCell' for #<SearchModulesScreen:0xaa219a0> (NameError)
'
*** First throw call stack:
(0xc69012 0x651e7e 0x2d1364 0x1965c9 0x16ef8fb 0x16ef9cf 0x16d81bb 0x16e8b4b 0x16852dd 0x6656b0 0x261ffc0 0x261433c 0x2614150 0x25920bc 0x2593227 0x25938e2 0xc31afe 0xc31a3d 0xc0f7c2 0xc0ef44 0xc0ee1b 0x2d7a7e3 0x2d7a668 0x1634ffc 0x35c7 0x2b65)
libc++abi.dylib: terminate called throwing an exception
((null))> rake aborted!
Command failed with status (1): [DYLD_FRAMEWORK_PATH="/Applications/Xcode.a...]
/Library/RubyMotion/lib/motion/project.rb:101:in `block in <top (required)>'
/Users/jh/.rvm/gems/ruby-1.9.3-p327@oucalc/bin/ruby_noexec_wrapper:14:in `eval'
/Users/jh/.rvm/gems/ruby-1.9.3-p327@oucalc/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => default => simulator
(See full trace by running task with --trace)

add_element: Create easy positioning attributes

I'm considering adding some additional functionality to the add_element method for easier positioning. Also, I'd like to change the name to just "add".

Example:

# NOTE that `.new` class methods alias to .alloc.init. I believe this works fine.

# Creates a horizontally-centered text field that stays centered on rotate
add UITextField.new, {
  top: 200,
  left: :auto,
  right: :auto,
  width: 200,
  height: 40
}

# Creates a right-aligned text field, 20 points from the right side
add UITextField.new, {
  top: 200,
  left: :auto,
  right: 20,
  width: 200,
  height: 40
}

# Creates a text field 20 points below the one just added.
# (definitely need input on this one)
add UITextField.new, {
  move_down: 60,
  left: :auto,
  right: 20,
  width: 200,
  height: 40
}

# Creates a text field vertically centered, dynamic width, 20 points left/right padding.
add UITextField.new, {
  top: :auto,
  bottom: :auto,
  left: 20,
  right: 20,
  width: :auto,
  height: 40
}

Need input on this.

Styling our app

In the readme of the 0.5, you tell us that the BigDay! Reminder App is built with ProMotion.
It could be interresting to tell us the gem or the basic workflow to style our app.

Like customise the nav bar color, embed custom font,...

With that, I would totally LOVE your gem !

Auto-populate table screens based on array of objects

Example:

class FriendsScreen < ProMotion::TableScreen
  title "Friends"
  cell_label_method :full_name
  cell_action :tapped_friend

  def friends
    @friends ||= [ Friend.new("Joe"), Friend.new("John"), Friend.new("Silas") ]
  end

  def table_data
    self.friends
  end

  def tapped_friend(friend)
    # Do something with the friend object here
  end
end

This would use the cell_label_method to call each object in the table_data array and construct the table:

if self.cell_label_method
  data.each do |obj|
    @table_cell[:label] = obj.send(self.cell_label_method)
  end
end

...something like that.

Thoughts?

textFieldShouldReturn not being called in ProMotion::Screen

textFieldShouldReturn doesn't appear to be getting called in a ProMotion::Screen. I've got the following code.

Can anyone reproduce this?

class LoginScreen < ProMotion::Screen

  def will_appear
    set_attributes self.view, {
      backgroundColor: 'white'.to_color
    }

    @screen_height = view.bounds.size.height
    @screen_width = view.bounds.size.width

    add_fields
  end

  def add_fields    
    # Login button
    @login = UIButton.buttonWithType(UIButtonTypeRoundedRect)
    @login.setTitle("Login", forState:UIControlStateNormal)
    @login.sizeToFit
    @login.frame = CGRectMake( 20, 100, @screen_width - 40, 55 ) # left, top, width, height
    add @login

    @login.when(UIControlEventTouchUpInside) do
      p @email.text
    end

    # Email
    @email = UITextField.alloc.initWithFrame [[20, 20], [@screen_width - 40, 26]]
    @email.placeholder = "Email Address"
    @email.textAlignment = UITextAlignmentLeft
    @email.keyboardType = UIKeyboardTypeEmailAddress
    @email.borderStyle = UITextBorderStyleRoundedRect
    @email.returnKeyType = UIReturnKeyNext
    add @email

    # Password
    @password = UITextField.alloc.initWithFrame [[20, 60], [@screen_width - 40, 26]]
    @password.placeholder = "Password"
    @password.textAlignment = UITextAlignmentLeft
    @password.keyboardType = UIKeyboardTypeEmailAddress
    @password.borderStyle = UITextBorderStyleRoundedRect
    @email.returnKeyType = UIReturnKeyDone
    add @password
  end

  def textFieldShouldReturn textField
    textField.resignFirstResponder
    true
  end
end

add_element: Allow for parameterized attribute setters?

How could we accomplish the situation like below with setTitle:forControlState:?

@button = add_element UIButton.buttonWithType(UIButtonTypeRoundedRect), {
  setTitle: "test", # it needs two parameters here, the title-string and the UIControlState (e.g. UIControlStateNormal)
  frame: CGRectMake(10, 150, 200, 40),
  backgroundColor: UIColor.blueColor
}

One suggestion would be to use a hash:

@button = add_element UIButton.buttonWithType(UIButtonTypeRoundedRect), {
  {setTitle: "test", forControlState: UIControlStateNormal},
  frame: CGRectMake(10, 150, 200, 40),
  backgroundColor: UIColor.blueColor
}

Not sure how to implement though.

Simple method to reload data for table screen

When the return of table_data is updated (I see it by getting the result in the console), Ii doesn't affect the table screen. If you have it in your gem, I'm sorry but I can't find it.

Why not have somethings like if we can code it :

class ContactsScreen < ProMotion::GroupedTableScreen
  def on_load
    self.loadJson
  end

  def table_data
    # get the data from the model and generate the cells
    return theCellsData
  end

  def loadJson
    # Loading stuff and generate the new contacts in the models
    self.reload_table_data
  end
end

TableScreen cleanup

This has been an eyesore for a while. I'm assigning it to @silasj to clean up for version 1.0. :) Also need lots of tests!

Objective-C stub for message `setShowsSelectionIndicator:' type `v@:c' not precompiled.

When trying to create a new UIPickerView as below this error is raised.

pickerView =  add_element UIPickerView.alloc.initWithFrame(CGRectMake(0, 45, 220, 40)), {     
  dataSource: self,
  delegate: self,
  showsSelectionIndicator: true
}

If instead of adding this to the args hash I explicitly set it as follows, no problems.

pickerView.showsSelectionIndicator=true

Add functional tests

Right now we have decent unit tests, but I'd like to add a full functional suite. I'll be working on this before version 1.0.

Adding a UIButton

This looks like an awesome library. I seem to be having some trouble adding a UIButton.

My last attempt was this:
@button = add UIButton.buttonWithType.UIButtonTypeRoundedRect, {
setTitle: "Schedule",
}

Not sure what I am missing. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.