mirror of
https://github.com/zhigang1992/ProMotion.git
synced 2026-05-25 01:31:37 +08:00
Tab bar refactor
* Fixes issue #167 * Added PM::TabBarController * Moved some PM::Tab methods into PM::TabBarController * Moved some tab-related accessors into PM::Tab * Allowed `open_tab` from AppDelegate and on the PM::TabBarController directly * Added tests * Added a method: set_tab_bar_badge(number) * Also fixed an error in the cell identifier creation code that was creating too many identifiers 75 specifications (144 requirements), 0 failures, 0 errors
This commit is contained in:
4
Rakefile
4
Rakefile
@@ -41,6 +41,10 @@ namespace :spec do
|
||||
App.config.instance_variable_set("@spec_files", spec_files)
|
||||
Rake::Task["simulator"].invoke
|
||||
end
|
||||
|
||||
task :func do
|
||||
Rake::Task["spec:functional"].invoke
|
||||
end
|
||||
|
||||
task :functional do
|
||||
App.config.spec_mode = true
|
||||
|
||||
44
lib/ProMotion/cocoatouch/tab_bar_controller.rb
Normal file
44
lib/ProMotion/cocoatouch/tab_bar_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
module ProMotion
|
||||
class TabBarController < UITabBarController
|
||||
|
||||
def self.new(*screens)
|
||||
tab_bar_controller = alloc.init
|
||||
|
||||
view_controllers = []
|
||||
|
||||
screens = screens.flatten.map { |s| s.respond_to?(:new) ? s.new : s } # Initialize any classes
|
||||
|
||||
tag_index = 0
|
||||
screens.each do |s|
|
||||
s.tabBarItem.tag = tag_index
|
||||
s.tab_bar = tab_bar_controller if s.respond_to?("tab_bar=")
|
||||
view_controllers << (s.navigationController || s)
|
||||
tag_index += 1
|
||||
s.on_load if s.respond_to?(:on_load)
|
||||
end
|
||||
|
||||
tab_bar_controller.viewControllers = view_controllers
|
||||
tab_bar_controller
|
||||
end
|
||||
|
||||
def open_tab(tab)
|
||||
if tab.is_a? String
|
||||
selected_tab_vc = find_tab(tab)
|
||||
elsif tab.is_a? Numeric
|
||||
selected_tab_vc = viewControllers[tab]
|
||||
end
|
||||
|
||||
if selected_tab_vc
|
||||
self.selectedViewController = selected_tab_vc if selected_tab_vc
|
||||
else
|
||||
PM.logger.error "Unable to open tab #{tab.to_s} -- not found."
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def find_tab(tab_title)
|
||||
self.viewControllers.select{ |vc| vc.tabBarItem.title == tab_title }.first
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,50 +1,32 @@
|
||||
module ProMotion
|
||||
module Tabs
|
||||
def tab_bar_controller(*screens)
|
||||
tab_bar_controller = UITabBarController.alloc.init
|
||||
|
||||
view_controllers = []
|
||||
tag_index = 0
|
||||
|
||||
screens.map! { |s| s.respond_to?(:new) ? s.new : s } # Initialize any classes
|
||||
|
||||
screens.each do |s|
|
||||
s = s.new if s.respond_to?(:new)
|
||||
|
||||
s.tabBarItem.tag = tag_index
|
||||
|
||||
s.parent_screen = self if self.is_a?(UIViewController) && s.respond_to?("parent_screen=")
|
||||
s.tab_bar = tab_bar_controller if s.respond_to?("tab_bar=")
|
||||
|
||||
view_controllers << (s.navigationController || s)
|
||||
|
||||
tag_index += 1
|
||||
|
||||
s.on_load if s.respond_to?(:on_load)
|
||||
end
|
||||
|
||||
tab_bar_controller.viewControllers = view_controllers
|
||||
tab_bar_controller
|
||||
end
|
||||
|
||||
attr_accessor :tab_bar, :tab_bar_item
|
||||
|
||||
def open_tab_bar(*screens)
|
||||
tab_bar = tab_bar_controller(*screens)
|
||||
self.tab_bar = PM::TabBarController.new(screens)
|
||||
|
||||
a = self.respond_to?(:open_root_screen) ? self : UIApplication.sharedApplication.delegate
|
||||
delegate = self.respond_to?(:open_root_screen) ? self : UIApplication.sharedApplication.delegate
|
||||
|
||||
a.open_root_screen(tab_bar)
|
||||
tab_bar
|
||||
delegate.open_root_screen(self.tab_bar)
|
||||
self.tab_bar
|
||||
end
|
||||
|
||||
def open_tab(tab)
|
||||
if tab.is_a? String
|
||||
return self.select(self.tab_bar, title: tab)
|
||||
elsif tab.is_a? Numeric
|
||||
self.tab_bar.selectedIndex = tab
|
||||
return self.tab_bar.viewControllers[tab]
|
||||
else
|
||||
$stderr.puts "Unable to open tab #{tab.to_s} because it isn't a string or number."
|
||||
end
|
||||
self.tab_bar.open_tab(tab)
|
||||
end
|
||||
|
||||
def set_tab_bar_item(args = {})
|
||||
self.tab_bar_item = args
|
||||
refresh_tab_bar_item
|
||||
end
|
||||
|
||||
def refresh_tab_bar_item
|
||||
self.tabBarItem = create_tab_bar_item(self.tab_bar_item) if self.tab_bar_item && self.respond_to?(:tabBarItem=)
|
||||
end
|
||||
|
||||
def set_tab_bar_badge(number)
|
||||
self.tab_bar_item[:badge] = number
|
||||
refresh_tab_bar_item
|
||||
end
|
||||
|
||||
def create_tab_bar_icon(icon, tag)
|
||||
@@ -69,19 +51,7 @@ module ProMotion
|
||||
|
||||
return tab_bar_item
|
||||
end
|
||||
|
||||
def select(tab_bar_controller, title: title)
|
||||
root_controller = nil
|
||||
tab_bar_controller.viewControllers.each do |vc|
|
||||
if vc.tabBarItem.title == title
|
||||
tab_bar_controller.selectedViewController = vc
|
||||
root_controller = vc
|
||||
break
|
||||
end
|
||||
end
|
||||
root_controller
|
||||
end
|
||||
|
||||
|
||||
def replace_current_item(tab_bar_controller, view_controller: vc)
|
||||
controllers = NSMutableArray.arrayWithArray(tab_bar_controller.viewControllers)
|
||||
controllers.replaceObjectAtIndex(tab_bar_controller.selectedIndex, withObject: vc)
|
||||
|
||||
@@ -5,7 +5,7 @@ module ProMotion
|
||||
include ProMotion::Tabs
|
||||
include ProMotion::SplitScreen if NSBundle.mainBundle.infoDictionary["UIDeviceFamily"].include?("2")
|
||||
|
||||
attr_accessor :parent_screen, :first_screen, :tab_bar_item, :tab_bar, :modal, :split_screen
|
||||
attr_accessor :parent_screen, :first_screen, :tab_bar_item, :modal, :split_screen
|
||||
|
||||
def on_create(args = {})
|
||||
unless self.is_a?(UIViewController)
|
||||
@@ -14,9 +14,7 @@ module ProMotion
|
||||
|
||||
self.title = self.class.send(:get_title)
|
||||
|
||||
args.each do |k, v|
|
||||
self.send("#{k}=", v) if self.respond_to?("#{k}=")
|
||||
end
|
||||
args.each { |k, v| self.send("#{k}=", v) if self.respond_to?("#{k}=") }
|
||||
|
||||
self.add_nav_bar(args) if args[:nav_bar]
|
||||
self.navigationController.toolbarHidden = !args[:toolbar] unless args[:toolbar].nil?
|
||||
@@ -45,15 +43,6 @@ module ProMotion
|
||||
val
|
||||
end
|
||||
|
||||
def set_tab_bar_item(args = {})
|
||||
self.tab_bar_item = args
|
||||
refresh_tab_bar_item
|
||||
end
|
||||
|
||||
def refresh_tab_bar_item
|
||||
self.tabBarItem = create_tab_bar_item(self.tab_bar_item) if self.tab_bar_item
|
||||
end
|
||||
|
||||
def add_nav_bar(args = {})
|
||||
self.navigation_controller ||= begin
|
||||
self.first_screen = true if self.respond_to?(:first_screen=)
|
||||
|
||||
@@ -71,8 +71,8 @@ module ProMotion
|
||||
|
||||
def set_data_cell_defaults(data_cell)
|
||||
data_cell[:cell_style] ||= UITableViewCellStyleDefault
|
||||
data_cell[:cell_identifier] ||= build_cell_identifier(data_cell)
|
||||
data_cell[:cell_class] ||= PM::TableViewCell
|
||||
data_cell[:cell_identifier] ||= build_cell_identifier(data_cell)
|
||||
|
||||
data_cell[:accessory] = {
|
||||
view: data_cell[:accessory],
|
||||
@@ -85,9 +85,9 @@ module ProMotion
|
||||
end
|
||||
|
||||
def build_cell_identifier(data_cell)
|
||||
ident = "#{data_cell[:cell_class]}"
|
||||
ident = "#{data_cell[:cell_class].to_s}"
|
||||
ident << "-#{data_cell[:stylename].to_s}" if data_cell[:stylename] # For Teacup
|
||||
ident << "-#{data_cell[:accessory][:view].to_s}" if data_cell[:accessory]
|
||||
ident << "-accessory" if data_cell[:accessory]
|
||||
ident << "-subtitle" if data_cell[:subtitle]
|
||||
ident << "-remoteimage" if data_cell[:remote_image]
|
||||
ident << "-image" if data_cell[:image]
|
||||
|
||||
@@ -50,5 +50,29 @@ describe "PM::Tabs" do
|
||||
@screen4.open_tab 0
|
||||
@tab_bar.selectedIndex.should == 0
|
||||
end
|
||||
|
||||
it "should allow opening a tab from the app_delegate" do
|
||||
@app.open_tab "Screen 2"
|
||||
@tab_bar.selectedIndex.should == 1
|
||||
@app.open_tab "Screen 3"
|
||||
@tab_bar.selectedIndex.should == 2
|
||||
@app.open_tab "Screen 4"
|
||||
@tab_bar.selectedIndex.should == 3
|
||||
@app.open_tab "Screen 1"
|
||||
@tab_bar.selectedIndex.should == 0
|
||||
end
|
||||
|
||||
it "should allow opening a tab by accessing the tab bar directly" do
|
||||
@tab_bar.open_tab "Screen 2"
|
||||
@tab_bar.selectedIndex.should == 1
|
||||
@tab_bar.open_tab "Screen 3"
|
||||
@tab_bar.selectedIndex.should == 2
|
||||
@tab_bar.open_tab "Screen 4"
|
||||
@tab_bar.selectedIndex.should == 3
|
||||
@tab_bar.open_tab "Screen 1"
|
||||
@tab_bar.selectedIndex.should == 0
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ describe "PM::TableViewCellModule" do
|
||||
action: :tapped_cell_1,
|
||||
height: 50, # manually changes the cell's height
|
||||
cell_style: UITableViewCellStyleSubtitle,
|
||||
cell_identifier: "Cell",
|
||||
cell_identifier: "Custom Cell",
|
||||
cell_class: PM::TableViewCell,
|
||||
layer: { masks_to_bounds: true },
|
||||
background_color: UIColor.redColor,
|
||||
@@ -54,12 +54,12 @@ describe "PM::TableViewCellModule" do
|
||||
end
|
||||
|
||||
it "should have the right custom re-use identifier" do
|
||||
@subject.reuseIdentifier.should == "Cell"
|
||||
@subject.reuseIdentifier.should == "Custom Cell"
|
||||
end
|
||||
it "should have the right generated re-use identifier" do
|
||||
ip = NSIndexPath.indexPathForRow(2, inSection: 1)
|
||||
subject = @screen.tableView(@screen.table_view, cellForRowAtIndexPath: ip)
|
||||
subject.reuseIdentifier.should == "Cell-accessory"
|
||||
subject.reuseIdentifier.should == "ProMotion::TableViewCell-accessory"
|
||||
end
|
||||
|
||||
it "should have the correct height" do
|
||||
|
||||
Reference in New Issue
Block a user