diff --git a/motion/ruby_motion_query/position.rb b/motion/ruby_motion_query/position.rb index f44a5ff..affddb7 100644 --- a/motion/ruby_motion_query/position.rb +++ b/motion/ruby_motion_query/position.rb @@ -106,22 +106,26 @@ module RubyMotionQuery self end - def resize_to_fit_subviews(padding = {}) + def resize_frame_to_fit_subviews(args = {}) selected.each do |view| - w = 0 - h = 0 + view.rmq.layout(subviews_bottom_right(view, args)) + end - view.subviews.each do |subview| - rect = subview.rmq.frame - w = [rect.right, w].max - h = [rect.bottom, h].max + self + end + alias :resize_to_fit_subviews :resize_frame_to_fit_subviews + + def resize_content_to_fit_subviews(args = {}) + selected.each do |view| + unless view.respond_to?(:contentSize) + puts "\n[RMQ ERROR] resize_content_to_fit_subviews must be called on a view that supports `contentSize`. Called on #{view}\n\n" + next end - rect = view.rmq.frame - w = rect.width if w == 0 - h = rect.height if h == 0 - - view.rmq.layout(w: (w + (padding[:right] || 0)), h: (h + (padding[:bottom] || 0))) + view.rmq.style do |st| + bottom_right = subviews_bottom_right(view, args) + st.content_size = CGSizeMake(bottom_right[:w], bottom_right[:h]) + end end self @@ -142,5 +146,27 @@ module RubyMotionQuery out end + private + + # Calculates the bottom right of a view using its subviews + # + # @return [Hash] + def subviews_bottom_right(view, args = {}) + w = 0 + h = 0 + + view.subviews.each do |subview| + rect = subview.rmq.frame + w = [rect.right, w].max + h = [rect.bottom, h].max + end + + rect = view.rmq.frame + w = rect.width if (w == 0 || args[:only_height]) + h = rect.height if (h == 0 || args[:only_width]) + + {w: (w + (args[:right] || 0)), h: (h + (args[:bottom] || 0))} + end + end end diff --git a/spec/position.rb b/spec/position.rb index 0fa0079..d762813 100644 --- a/spec/position.rb +++ b/spec/position.rb @@ -101,7 +101,7 @@ describe 'position' do view.rmq.append(UIButton).layout(h: 50, w: 10) view.rmq.append(UIButton).layout(h: 5, w: 1) view.size.width.should == 20 - view.rmq.resize_to_fit_subviews + view.rmq.resize_frame_to_fit_subviews view.size.width.should == 10 view.size.height.should == 50 end @@ -113,7 +113,7 @@ describe 'position' do view.rmq.append(UIView).layout(h: 5, w: 1) view.size.width.should == 20 view.size.height.should == 100 - view.rmq.resize_to_fit_subviews + view.rmq.resize_frame_to_fit_subviews view.size.width.should == 70 view.size.height.should == 500 end @@ -127,26 +127,120 @@ describe 'position' do view.size.height.should == 100 # Just right - view.rmq.resize_to_fit_subviews({right: 101}) + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({right: 101}) view.size.width.should == 171 view.size.height.should == 500 # Just bottom - view.rmq.resize_to_fit_subviews({bottom: 13}) + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({bottom: 13}) view.size.width.should == 70 view.size.height.should == 513 # Both right & bottom - view.rmq.resize_to_fit_subviews({right: 101, bottom: 13}) + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({right: 101, bottom: 13}) view.size.width.should == 171 view.size.height.should == 513 # Negative values - view.rmq.resize_to_fit_subviews({right: -1, bottom: -1}) + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({right: -1, bottom: -1}) view.size.width.should == 69 view.size.height.should == 499 end + it "should resize a view's frame without changing height if specified" do + view = @vc.rmq.append(UIView).layout(h: 100, w: 20).get + view.rmq.append(UIButton).layout(h: 50, w: 10) + view.rmq.append(UILabel).layout(h: 500, w: 70) + view.rmq.append(UIView).layout(h: 5, w: 1) + view.size.width.should == 20 + view.size.height.should == 100 + + view.rmq.resize_frame_to_fit_subviews({only_height: true}) + view.size.width.should == 20 + view.size.height.should == 500 + + # With bottom padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_height: true, bottom: 10}) + view.size.width.should == 20 + view.size.height.should == 510 + + # With right padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_height: true, right: 10}) + view.size.width.should == 30 + view.size.height.should == 500 + + # With both padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_height: true, bottom:21, right: 10}) + view.size.width.should == 30 + view.size.height.should == 521 + end + + it "should resize a view's frame without changing width if specified" do + view = @vc.rmq.append(UIView).layout(h: 100, w: 20).get + view.rmq.append(UIButton).layout(h: 50, w: 10) + view.rmq.append(UILabel).layout(h: 500, w: 70) + view.rmq.append(UIView).layout(h: 5, w: 1) + view.size.width.should == 20 + view.size.height.should == 100 + + view.rmq.resize_frame_to_fit_subviews({only_width: true}) + view.size.width.should == 70 + view.size.height.should == 100 + + # With bottom padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_width: true, bottom: 10}) + view.size.width.should == 70 + view.size.height.should == 110 + + # With right padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_width: true, right: 10}) + view.size.width.should == 80 + view.size.height.should == 100 + + # With both padding + view.rmq.layout(h:100, w:20) + view.rmq.resize_frame_to_fit_subviews({only_width: true, bottom:21, right: 10}) + view.size.width.should == 80 + view.size.height.should == 121 + end + + it "should set a UIScrollView's contentSize property automatically" do + view = @vc.rmq.append(UIScrollView).layout(h: 100, w: 20).get + view.rmq.append(UIButton).layout(h: 50, w: 10) + view.rmq.append(UILabel).layout(h: 500, w: 70) + view.rmq.append(UIView).layout(h: 5, w: 1) + + view.contentSize.should == CGSizeZero + + view.rmq.resize_content_to_fit_subviews + view.contentSize.should == CGSizeMake(70, 500) + + # Right padding + view.rmq.resize_content_to_fit_subviews({right: 20}) + view.contentSize.should == CGSizeMake(90, 500) + + # Bottom padding + view.rmq.resize_content_to_fit_subviews({bottom: 21}) + view.contentSize.should == CGSizeMake(70, 521) + + # Right and bottom padding + view.rmq.resize_content_to_fit_subviews({right: 19, bottom: 2}) + view.contentSize.should == CGSizeMake(89, 502) + + # Negative padding + view.rmq.resize_content_to_fit_subviews({right: -2, bottom: -4}) + view.contentSize.should == CGSizeMake(68, 496) + end + it 'should nudge a view in various directions' do view = @vc.rmq.append(UILabel).get view.origin.x.should == 0