HipByte / Flow

Cross-platform libraries for RubyMotion
BSD 2-Clause "Simplified" License
141 stars 29 forks source link

undefined method boundingRectWithSize:options:context: #31

Closed andrewhavens closed 7 years ago

andrewhavens commented 8 years ago

I'm trying to work with UI::List but I am running into this issue:

label.rb:10:in `measure:': undefined method `boundingRectWithSize:options:context:' for nil:NilClass (NoMethodError)
    from view.rb:83:in `update_layout'
    from list.rb:51:in `tableView:cellForRowAtIndexPath:'

It looks like the label that I am adding to my row is causing this error because attributedText is nil. But according to the Apple docs, it is always expected to be nil by default. I am setting the text (not attributed text) attribute.

    def measure(width, height)
      size = [width.nan? ? Float::MAX : width, Float::MAX]
      rect = proxy.attributedText.boundingRectWithSize(size, options:NSStringDrawingUsesLineFragmentOrigin, context:nil)
      [width, rect.size.height]
    end
jjaffeux commented 8 years ago

@andrewhavens first, UI::List is one of the area that still needs a lot of work.

Concerning your question, can you provide a small sample of what you are trying to accomplish please ?

andrewhavens commented 8 years ago

This sample works on Android but does not work on iOS (with the error mentioned above):

class EventRow < UI::ListRow
  def initialize
    self.flex_direction = :column
    self.padding = [10, 10, 10, 10]
    add_child(title)
    add_child(start_time)
    add_child(location)
  end

  def update(data)
    title.text = data["title"]
    start_time.text = data["start_time"]
    location.text = data.fetch("venue", {})["title"]
  end

  def title
    @title_label ||= begin
      label = UI::Label.new
      font_name = ios? ? "Helvetica" : "Roboto-Regular"
      label.font = { name: font_name, size: 18 }
      label
    end
  end

  def start_time
    @start_time_label ||= begin
      label = UI::Label.new
      font_name = ios? ? "Helvetica" : "Roboto-Regular"
      label.font = { name: font_name, size: 12 }
      label
    end
  end

  def location
    @location_label ||= begin
      label = UI::Label.new
      font_name = ios? ? "Helvetica" : "Roboto-Regular"
      label.font = { name: font_name, size: 12 }
      label
    end
  end
end
jjaffeux commented 8 years ago

@andrewhavens Are your sure none of this is nil ? Try to add .to_s to be sure it's not the problem.

title.text = data["title"].to_s
start_time.text = data["start_time"].to_s
location.text = data.fetch("venue", {})["title"].to_s
andrewhavens commented 8 years ago

@jjaffeux Yes, proxy.attributedText is nil. The same thing happens when setting label.title = nil or simply not setting a title at all since attributedText is nil when the label is initialized.

So it seems like the measure method does not know what to do with an empty label. When it's nil (or an empty string), it should calculate the size as if the view does not exist, or is hidden, because it doesn't take up any space.