Skip to content

Instantly share code, notes, and snippets.

@dblandin
Created August 22, 2013 05:11
Show Gist options
  • Save dblandin/6303425 to your computer and use it in GitHub Desktop.
Save dblandin/6303425 to your computer and use it in GitHub Desktop.
Variable-height UILabel with auto layout in RubyMotion In response to: http://stackoverflow.com/questions/17959964/uilabel-dynamic-height-within-uitableviewcell-acts-erratic
class EventCell < UITableViewCell
IDENTIFIER = 'EventCell'
PADDING = 10
LEFT_MARGIN = 40
RIGHT_MARGIN = 20
attr_reader :event
def initWithStyle(style, reuseIdentifier: reuse_identifier)
super.tap do |cell|
cell.contentView.addSubview(title)
cell.contentView.addSubview(location)
cell.setup_constraints
end
end
def event=(event)
@event = event
title.text = event[:title]
location.text = event[:location]
end
def setup_constraints
['H:|-left_margin-[title]-right_margin-|',
'H:|-left_margin-[location]-right_margin-|',
'V:|[title]-padding-[location]'].each do |visual_format|
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
visual_format,
options: 0,
metrics: metrics,
views: subviews_dict))
end
end
def metrics
{ 'left_margin' => LEFT_MARGIN,
'right_margin' => RIGHT_MARGIN,
'padding' => PADDING }
end
def subviews_dict
{ 'title' => title,
'location' => location }
end
def intrinsicContentSize
content_height = labels.inject(0) {|sum, label| sum + label.intrinsicContentSize.height }
CGSizeMake(-1, content_height + PADDING)
end
def labels
[title, location]
end
def title
@title ||= build_label.tap do |label|
label.font = UIFont.fontWithName('Helvetica', size: 36.0)
end
end
def location
@location ||= build_label.tap do |label|
label.font = UIFont.fontWithName('Helvetica', size: 16.0)
end
end
def build_label
UILabel.alloc.init.tap do |label|
label.lineBreakMode = NSLineBreakByWordWrapping
label.numberOfLines = 0
label.setPreferredMaxLayoutWidth(contentView.size.width - (LEFT_MARGIN + RIGHT_MARGIN))
label.translatesAutoresizingMaskIntoConstraints = false
end
end
end
class EventsController < UITableViewController
def viewDidLoad
super
register_cells
tableView.dataSource = self
tableView.delegate = self
end
def register_cells
tableView.registerClass(EventCell, forCellReuseIdentifier: EventCell::IDENTIFIER)
end
def tableView(table_view, numberOfRowsInSection: section)
events.count
end
def tableView(table_view, cellForRowAtIndexPath: index_path)
table_view.dequeueReusableCellWithIdentifier(EventCell::IDENTIFIER).tap do |cell|
event = events[index_path.row]
cell.event = event
end
end
def tableView(table_view, heightForRowAtIndexPath: index_path)
cell = table_view.dataSource.tableView(table_view, cellForRowAtIndexPath: index_path)
cell.intrinsicContentSize.height
end
def events
[{ title: "Flashlight Tour on a 'Haunted' Aircraft Carrier",
location: 'USS Hornet Museum' },
{ title: 'Dinner and a Movie',
location: 'Grant Park' }]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment