omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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

    Pythonista
    cells variable share
    5
    29
    18398
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • JonB
      JonB last edited by JonB

      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.

      1 Reply Last reply Reply Quote 1
      • cook
        cook last edited by

        @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 :)

        1 Reply Last reply Reply Quote 0
        • ccc
          ccc last edited by

          @cook You have repeated 1 << 5 four times but that is not what @JonB did above. He is flipping different bits while you are flipping the same bit multiple times.

          1 Reply Last reply Reply Quote 0
          • cook
            cook last edited by

            @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()
            
            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by JonB

              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 nonzero

              import 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.

              1 Reply Last reply Reply Quote 0
              • cook
                cook last edited by

                @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!

                1 Reply Last reply Reply Quote 0
                • cook
                  cook last edited by

                  @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?

                  1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB last edited by

                    turns out autoresizingmask might be the same as flex... addConstraints would be what we want for content_view. I have not tried it yet.

                    1 Reply Last reply Reply Quote 0
                    • lewisl
                      lewisl last edited by

                      I am trying to put images into the rows. This did not work to set a row height.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post
                      Powered by NodeBB Forums | Contributors