jamonholmgren / promotion Goto Github PK
View Code? Open in Web Editor NEWProMotion is a RubyMotion gem that makes iPhone development less like Objective-C and more like Ruby.
License: MIT License
ProMotion is a RubyMotion gem that makes iPhone development less like Objective-C and more like Ruby.
License: MIT License
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.
Adding BubbleWrap to a new ProMotion app causes this error:
uninitialized constant ProMotion::ScreenModule (NameError)
Investigating.
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.
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
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
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
Any hints on setting a font size for table cell data with promotion? Thanks!
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.
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 ?
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?
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.
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.
(main)> 2013-05-30 16:05:05.421 mobileAdmin2[6650:c07] _searcha:in searchDisplayController:shouldReloadTableForSearchString:': undefined method
search' 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 method
search' for true:TrueClass (NoMethodError)
When I'm set :background_color in the cell definition the color will not get changed.
With my workaround I'm set the color in def layoutSubviews of the TableViewCell but this can't be the solution...
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!
I think the element styling needs more work and potentially a new paradigm.
add
method (previously add_element
) works pretty well but still litters your controllers with view codeI'd like some ideas. Potential discussion points:
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!
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)
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];
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
Hello,
Is there an easy way of settings backgroundColor in the same way as I set for example Title for a screen?
Hi,
I'd like to add something like ViewDeck or ECSlidingViewController in my App.
Any idea how to integrate it ?
Thanks :-)
Travis-CI now supports RubyMotion, so we need to implement it.
http://about.travis-ci.org/blog/introducing-mac-ios-rubymotion-testing/
Assigned to me, pending 3 minutes of free time.
Allow snake_case attributes on set_attributes
(and its cousins, add
and add_to
):
set_attributes UILabel.new, {
background_color: "#FFFFFF".to_color,
line_break_mode: UILineBreakModeWordWrap
}
It's relatively easy to do.
I just read the blog post about RubyMotion 2.0 (adding OSX support):
http://blog.rubymotion.com/post/49943751398/rubymotion-goes-2-0-and-gets-osx-support-templates-and
This is great news! I plan to start playing around with it at some point.
This is a ticket to discuss whether it makes sense to include OSX support in ProMotion or not. Feel free to give your impressions/thoughts.
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.
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?
I think it would be great if we could simplify the calls to should_rotate(orientation)
(iOS5) and should_autorotate
(iOS 6) so that we only need to implement one method in our code.
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
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)
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)
Duplicated code according to CodeClimate. That's the only bad smell in the gem so far.
https://codeclimate.com/github/clearsightstudio/ProMotion/ProMotion::ScreenModule
Let's get this fixed...should be simple.
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?
ProMotion appears to be hanging on to some screens longer than it should. Let's dig into this and figure out what's happening.
Add in an iPad SplitScreen. Extract from BigDay! code.
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 UIViewController
s 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.
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
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?
(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)
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.
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 !
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
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
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.
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
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!
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
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.
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?
Remove embedded MotionTable code and extract into the motion-table gem.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.