Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
[Share] A skeleton for making and testing variable height cells for a ScrollView
-
UIViews have a autoresizingMask property, and an addConstraint() method, together these define autolayout, I think. @Webmaster4o, this would be a good addition to ui2, as it gives more powerful layout.
autoresizingMask takes an integer bitmask, which you add up the options you want:
UIViewAutoresizingNone = 0 UIViewAutoresizingFlexibleLeftMargin = 1 << 0 UIViewAutoresizingFlexibleWidth = 1 << 1 UIViewAutoresizingFlexibleRightMargin = 1 << 2 UIViewAutoresizingFlexibleTopMargin = 1 << 3 UIViewAutoresizingFlexibleHeight = 1 << 4 UIViewAutoresizingFlexibleBottomMargin = 1 << 5 ObjCInstance(v).autoresizeMask=UIViewAutoResizingFlexibleWidth+UIViewAutoResizingWidth
it should be possible to apply these to tableviewcells, and to the tableview itself..
UITableViewAutomaticDimension is -1.0, you set the rowheight to this value.
-
@jonb ...hmm... This is way over my head. I've tried this but it doesn't work.
import ui from objc_util import * class TableData(object): def __init__(self): self.data = [{'value': str(i), 'height': i+40} for i in range(10)] def tableview_number_of_rows(self, tableview, section): return len(self.data) def tableview_cell_for_row(self, tableview, section, row): cell = ui.TableViewCell() label = ui.Label() label.text = self.data[row]['value'] label.number_of_lines = 0 label_objc = ObjCInstance(label) UIViewAutoresizingFlexibleTopMargin = 1 << 5 UIViewAutoresizingFlexibleBottomMargin = 1 << 5 UIViewAutoresizingFlexibleHeight = 1 << 5 UIViewAutoresizingFlexibleLeftMargin = 1 << 5 label_objc.autoresizeMask = UIViewAutoresizingFlexibleTopMargin + UIViewAutoresizingFlexibleBottomMargin + UIViewAutoresizingFlexibleHeight + UIViewAutoresizingFlexibleLeftMargin label.height = self.data[row]['height'] cell.content_view.add_subview(label) return cell tv = ui.TableView() tv.data_source = TableData() tv_objc = ObjCInstance(tv) tv_objc.rowHeight = -1.0 #UITableViewAutomaticDimension tv_objc.estimatedRowHeight = 40.0 tv.present()
... Scratching my head :)
-
-
@ccc ... I have no clue what flipping bits do! :)
But even if I apparently flip the bits differently I don't get any bit closer !
I'm in deep water...drowning...and the objc piranhas are coming.
Adjusted code ..maybe a step closer ...(?):
import ui from objc_util import * class TableData(object): def __init__(self): self.data = [{'value': str(i), 'height': i+40} for i in range(10)] def tableview_number_of_rows(self, tableview, section): return len(self.data) def tableview_cell_for_row(self, tableview, section, row): cell = ui.TableViewCell() label = ui.Label() label.text = self.data[row]['value'] label.number_of_lines = 0 label_objc = ObjCInstance(label) UIViewAutoresizingNone = 0 UIViewAutoresizingFlexibleLeftMargin = 1 << 0 UIViewAutoresizingFlexibleWidth = 1 << 1 UIViewAutoresizingFlexibleRightMargin = 1 << 2 UIViewAutoresizingFlexibleTopMargin = 1 << 3 UIViewAutoresizingFlexibleHeight = 1 << 4 UIViewAutoresizingFlexibleBottomMargin = 1 << 5 label_objc.autoresizeMask = UIViewAutoresizingFlexibleWidth + UIViewAutoresizingFlexibleTopMargin + UIViewAutoresizingFlexibleBottomMargin + UIViewAutoresizingFlexibleHeight label.height = self.data[row]['height'] cell.content_view.add_subview(label) return cell tv = ui.TableView() tv.data_source = TableData() tv_objc = ObjCInstance(tv) tv_objc.rowHeight = -1.0 #UITableViewAutomaticDimension tv_objc.estimatedRowHeight = 40.0 tv.present()
-
Turns out the textlabel already has constraints built in, so all you have to do is:
set number_of_lines=0
set tableview.row_height=-1
set ObjCInstance(tv).estimatedHeight to something nonzeroimport ui, faker, random from objc_util import * f=faker.Faker() items=[f.text(random.randint(10,200)) for i in range(20)] class MyTableViewDataSource (object): def tableview_number_of_rows(self, tableview, section): # Return the number of rows in the section return 20 def tableview_cell_for_row(self, tableview, section, row): # Create and return a cell for the given section/row cell = ui.TableViewCell() cell.text_label.text = items[row] cell.text_label.number_of_lines=0 return cell v=ui.TableView() v.frame=(0,0,320,576) v.row_height=-1 v.data_source=MyTableViewDataSource() ObjCInstance(v).estimatedRowHeight=44 v.present('sheet')
Basically we get auto resizing text cells with basically three added lines of code!
@omz -- providing estimatedRowHeight access in ui.TableView would make this more accessible. -
@jonb incredible. Will give it a shot.
Thanks for helping (...doing all the work) figure this out. I think it's really useful and also a very easy approach!
-
@jonb now... Do you think this is possible to do for a view that is added to the
content_view
of a cell?
Will that require flipping bits? -
turns out autoresizingmask might be the same as flex... addConstraints would be what we want for content_view. I have not tried it yet.
-
I am trying to put images into the rows. This did not work to set a row height.