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.


    Adding a label to TableViewCell, it's offset by one?...

    Pythonista
    5
    28
    21942
    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.
    • Phuket2
      Phuket2 last edited by

      I assume this is a bug, if it is so be it... I hope not....
      But I am adding a label to a TableViewCell. And magically it's offset by one. I guess it's something to do with section. I have tried and tried to fix it, but can not. The other problem is that the view is Cell is not being doubled buffered correctly (or whatever you call it) if you pull down on my list you will see that the labels I created are no longer drawn. I tried both ways. Adding my ui.Label to cell.content_view as stated in the docs and I tried also cell.add_subview. Same results.

      Any advice appreciated

      import ui
      
      _days = ['Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday','Sunday']
      
      # the colors corresponding to days of the week
      # thai people often wear these colors on the day 
      # of the week. Is related to the Royal Family.
      # Currently, the most important is yellow, the
      # The King of Thailand was born on a Monday
      # He is the longest severing and living monach
      # in the world.
      _colors = ['yellow', 'pink', 'green', 'orange', 'blue', 'purple', 'red']
      
      
      class MyTableViewDataSource (object):
      	def tableview_number_of_sections(self, tableview):
      		# Return the number of sections (defaults to 1)
      		return 1
      
      	def tableview_number_of_rows(self, tableview, section):
      		# Return the number of rows in the section
      		return len(_days) 
      
      	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 = _days[row]
      		
      		# create a label inside the cell
      		# the documentation says to add it to the
      		# content view
      		lb = ui.Label()
      		lb.x , lb.y = 15, 30
      		lb.width = cell.width - lb.x
      		lb.text_color = _colors[row]
      		lb.text = _colors[row]
      		cell.content_view.add_subview(lb)
      		cell.add_subview(lb)
      		return cell
      
      	def tableview_title_for_header(self, tableview, section):
      		# Return a title for the given section.
      		# If this is not implemented, no section headers will be shown
      		if section == 0:
      			return 'Week Days'
      		
      
      	def tableview_can_delete(self, tableview, section, row):
      		# Return True if the user should be able to delete the given row.
      		return True
      
      	def tableview_can_move(self, tableview, section, row):
      		# Return True if a reordering control should be shown for the given row (in editing mode).
      		return True
      
      	def tableview_delete(self, tableview, section, row):
      		# Called when the user confirms deletion of the given row.
      		pass
      
      	def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
      		# Called when the user moves a row with the reordering control (in editing mode).
      		pass
      
      if __name__ == '__main__':
      	frame = (0,0,540,576)
      	v = ui.View()
      	tb = ui.TableView()
      	tb.frame = frame
      	v.add_subview(tb)
      	tb.data_source = MyTableViewDataSource()
      	v.present('sheet')
      
      1 Reply Last reply Reply Quote 0
      • Phuket2
        Phuket2 last edited by

        Oh, I should also mention that when a cell is selected, it also clears my custom items. It does not matter if I have a delegate of not.

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

          The problem is that your labels are too high. The default size for new views is 100x100, so your labels are bigger than the cells they're in, which leads to all sorts of weirdness.

          You could simply set their height to something like 15 (or use size_to_fit), but there's actually an easier way, which is to create 'subtitle'-style cells, which come with a built-in secondary label:

          def tableview_cell_for_row(self, tableview, section, row):
              cell = ui.TableViewCell('subtitle')
              cell.text_label.text = _days[row]
              cell.detail_text_label.text = _colors[row]
              cell.detail_text_label.text_color = _colors[row]
              return cell
          
          1 Reply Last reply Reply Quote 0
          • Phuket2
            Phuket2 last edited by

            @Omz, thanks. I just did the height for now and it worked. I will look at the other method for sub text tomorrow, 00:45 now :) getting old

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

              See colors_of_the_week.py.

              • _days can be replaced with the standard library's calendar.day_name
              • _day_color_dict can be created by zipping calendar.day_name and the color list within a dict comprehension
              • Light colors show up better on a black background
              • Omz's subtitle cells are quite slick
              • TableView can be presented directly without embedding in an outer View
              • TableView.size_to_fit() works quite well... I will use that more often.

              Have a good red (Sunday).

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

                @ccc, thanks. I can't seem to get cell.detail_text_label.text working. The object is None. The docs say that for certain cell types (default style) the object will be None. For the life of me I can't see a cell STYLE attr in either the docs or when I print dir(cell). I am fairly certain, it has nothing to do with accessory_type.
                Any help appreciated. It's driving me nuts. I am sure it's going to be something simple.

                Btw, I have a mainly red shirt on today :)

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

                  @Phuket2 You need to specify the cell style when creating the cell (see my code snippet); there's no way to modify it afterwards.

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

                    Sorry, another stupid mistake. I totally missed the parameter that omz passed in his example code. Bashing my head on the table now.
                    Is default and subtitle the only 2 styles available or are there more?

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

                      There are also 'value1' and 'value2' (both also have a detail_text_label, but positioned differently).

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

                        Ok, thanks, I will try them out. But it does all really work nicely once you do a little work with it. And very fast.
                        Thanks again.

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

                          I think 'value1' looks the best for this example.

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

                            I did it like this @ccc. I have to work out the cell selection. I know it's a bit funky with all the spaces etc... Just trying to get my head around the possibilities. But yes also good to know about value1 and value2.
                            And added a make_cell function, only a matter of time before you told me to :)

                            import ui
                            
                            
                            _days = ['Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday','Sunday']
                            
                            # the colors corresponding to days of the week
                            # thai people often wear these colors on the day 
                            # of the week. Is related to the Royal Family.
                            # Currently, the most important is yellow, the
                            # The King of Thailand was born on a Monday
                            # He is the longest severing and living monach
                            # in the world.
                            _colors = ['yellow', 'pink', 'green', 'orange', 'blue', 'purple', 'red']
                            
                            def make_cell(row):
                            	cell = ui.TableViewCell('subtitle')
                            	btn = ui.Button()
                            	btn.width = btn.height = 28
                            	
                            	btn.x, btn.y = 8 , (cell.height / 2) - (btn.height / 2)
                            	
                            	btn.background_color = _colors[row]
                            	cell.content_view.add_subview(btn)
                            	cell.text_label.text = ' ' * 6 + _days[row]
                            	
                            	cell.detail_text_label.text = ' ' * 9 + _colors[row].title()
                            	
                            	return cell
                            	
                            class MyTableViewDataSource (object):
                            	def tableview_number_of_sections(self, tableview):
                            		# Return the number of sections (defaults to 1)
                            		return 1
                            
                            	def tableview_number_of_rows(self, tableview, section):
                            		# Return the number of rows in the section
                            		return len(_days) 
                            
                            	def tableview_cell_for_row(self, tableview, section, row):
                            		# Create and return a cell for the given section/row
                            
                            		return make_cell(row)
                            		
                            
                            	def tableview_title_for_header(self, tableview, section):
                            		# Return a title for the given section.
                            		# If this is not implemented, no section headers will be shown
                            		if section == 0:
                            			return 'Week Days'
                            		
                            
                            	def tableview_can_delete(self, tableview, section, row):
                            		# Return True if the user should be able to delete the given row.
                            		return False
                            
                            	def tableview_can_move(self, tableview, section, row):
                            		# Return True if a reordering control should be shown for the given row (in editing mode).
                            		return False 
                            
                            	def tableview_delete(self, tableview, section, row):
                            		# Called when the user confirms deletion of the given row.
                            		pass
                            
                            	def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
                            		# Called when the user moves a row with the reordering control (in editing mode).
                            		pass
                            
                            if __name__ == '__main__':
                            	
                            	frame = (0,0,540,576)
                            
                            	tb = ui.TableView()
                            	tb.name = 'Thai Color Chart'
                            	tb.frame = frame
                            	tb.data_source = MyTableViewDataSource()
                            	tb.present('sheet')
                            
                            1 Reply Last reply Reply Quote 0
                            • ccc
                              ccc last edited by

                              You might consider adding cell_type to make_cell():

                              def make_cell(row, cell_type='subtitle'):  # None, 'value1', 'value2' are other possibilities
                                  cell = ui.TableViewCell(cell_type)
                                  [ ... ]
                              
                              1 Reply Last reply Reply Quote 0
                              • Phuket2
                                Phuket2 last edited by

                                @ccc, yes thanks. I am working on something else with tableview at the moment and I did exactly that (I also commented all the params so not to forget them). Only wrote this to convey my issue I was having with tableview. Easy data to convey. Wrote the big blurb about the king, more like a reflex. You live here long enough you assimilate into the culture.
                                But regardless you are right should be written correctly.
                                I love the implementation of the tableview, but I think a margin/indent attr would be great, also a virtual mode. I can see it's semi virtual. What I can see is that not all cells are fetched at once. Looks like omz has implemented some fetch routine based on the visible cells plus a read ahead amount of cells.
                                But if you had a create cell and a draw cell, you could easily have max(int) rows. No real performance hit as long as your data retrieval method was fast enough. In the days when memory was scarce and CPU power was low, and networks slower, we could do some great things with virtual lists. We had to steer away from databases for this to work. Our data files were variable length, but just had index files we could binary search our keys that pointed to a location in the file with a length (for the day they were massive files) I know, not great for updates. We had an update system also. But we replaced all our customers data files monthly. Yeah, the days of cd and dvd distribution:)
                                Sorry to digress, but some of the old ideas are ok for some problems.

                                Anyway, my 2 cents worth :)

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

                                  I got some grief over the colors I selected for this example from many thai girls ( I didn't select any colors, just used the color name), So then picked the colors with them and made a new list. Is more representative of the colors. Also added another list for the thai words. I was happy it worked so easily, but pretty sure the utf-8 comment up the top helps.

                                  Hmm, I am very new to Unicode etc (we used to call double byte) here on iOS. Even it's just copy paste into a list, it's the first I have done in Pythonista. If you are interested to run the code, I have included a screen shot what the output should look like. I am not sure if it renders correctly on my iPad because of my settings or not.

                                  #coding: utf-8
                                  import ui
                                  
                                  
                                  _days = ['Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday','Sunday']
                                  
                                  # the colors corresponding to days of the week
                                  # thai people often wear these colors on the day 
                                  # of the week. Is related to the Royal Family.
                                  # Currently, the most important is yellow, the
                                  # The King of Thailand was born on a Monday
                                  # He is the longest severing and living monach
                                  # in the world.
                                  _real_colors = ['gold', 'deeppink', 'green', 'orangered', 'blue', 'purple', 'red']
                                  
                                  _colors = ['yellow', 'pink', 'green', 'orange', 'blue', 'purple', 'red']
                                  
                                  _thai_script_colors = ['สีเหลือง', 'สีชมพู','สีเขียว','สีส้ม','สีฟ้า', 'สีม่วง', 'สีแดง']
                                  
                                  
                                  def make_cell(row , cell_type = 'subtitle'):
                                  	#TableViewCell params None,subtitle,value1,value2
                                  	cell = ui.TableViewCell(cell_type)
                                  	btn = ui.Button()
                                  	btn.width = btn.height = 28
                                  	
                                  	btn.x, btn.y = 8 , (cell.height / 2) - (btn.height / 2)
                                  	
                                  	btn.background_color = _real_colors[row]
                                  	cell.content_view.add_subview(btn)
                                  	cell.text_label.text = ' ' * 6 + _days[row]
                                  	
                                  	cell.detail_text_label.text = ' ' * 9 + _colors[row].title()
                                  	
                                  	if _colors[row] <> _real_colors[row]:
                                  		cell.detail_text_label.text += ' (' + _real_colors[row] + ')'
                                  		
                                  	cell.detail_text_label.text += '  ' + _thai_script_colors[row]
                                  	
                                  	return cell
                                  	
                                  class MyTableViewDataSource (object):
                                  	def tableview_number_of_sections(self, tableview):
                                  		# Return the number of sections (defaults to 1)
                                  		return 1
                                  
                                  	def tableview_number_of_rows(self, tableview, section):
                                  		# Return the number of rows in the section
                                  		return len(_days) 
                                  
                                  	def tableview_cell_for_row(self, tableview, section, row):
                                  		# Create and return a cell for the given section/row
                                  
                                  		return make_cell(row)
                                  		
                                  
                                  	def tableview_title_for_header(self, tableview, section):
                                  		# Return a title for the given section.
                                  		# If this is not implemented, no section headers will be shown
                                  		if section == 0:
                                  			return 'Week Days'
                                  		
                                  
                                  	def tableview_can_delete(self, tableview, section, row):
                                  		# Return True if the user should be able to delete the given row.
                                  		return False
                                  
                                  	def tableview_can_move(self, tableview, section, row):
                                  		# Return True if a reordering control should be shown for the given row (in editing mode).
                                  		return False 
                                  
                                  	def tableview_delete(self, tableview, section, row):
                                  		# Called when the user confirms deletion of the given row.
                                  		pass
                                  
                                  	def tableview_move_row(self, tableview, from_section, from_row, to_section, to_row):
                                  		# Called when the user moves a row with the reordering control (in editing mode).
                                  		pass
                                  
                                  if __name__ == '__main__':
                                  	
                                  	frame = (0,0,540,576)
                                  
                                  	tb = ui.TableView()
                                  	tb.name = 'Thai Color Chart'
                                  	tb.frame = frame
                                  	tb.data_source = MyTableViewDataSource()
                                  	tb.present('sheet')
                                  
                                  

                                  Image of the screen rendered with thai text
                                  https://www.dropbox.com/s/td54lkujo6lgnrg/file 12-07-2015 22 29 51.png?dl=0

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

                                    (I'm impressed Firefox can render those characters - on this FORUM.) :-)

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

                                      The thai chars also rendering in safari in the forum. I guess we should not be so surprised, handling of multi byte scripts have come so far (to tell the truth, I can't remember if thai is multi byte or not, I think it has to be though) I was more worried about the python side. Seems you have to me very careful when you start dealing with Unicode scripts in python. No experience, just what I read.

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

                                        Thai characters are double byte:

                                        # coding: utf-8
                                        print('\nunicode, hex, dec')
                                        for c in u'สีเหลือง':
                                            print('{0}, {0!r}, {1}'.format(c, ord(c)))
                                        

                                        http://pyformat.info is a great source of info on str.format().

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

                                          @phuket2 and I guess my Japanese customers (at least) still use DBCS - with SI and SO etc.

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

                                            @MartinPacker, don't really know what SI and SO is. I have been out of it too long. I haven't commercially coded for around 20 years probably longer than that. I have been retired going on 16 years now. So to say I am out of touch is a huge understatement. But I wish Python had been mainstream when I was programming. I guess even if it was, the processors of the day were just too slow. We could use high level languages for the basic parts of the interface, but had to resort to c for many things. Nothing wrong with c when you are in the groove, we basically released a new app every month, that's scary with c. Well, I thought it was. Most the time we got it right, but not all the time. Also dealing with Japanese, big datasets with our own search routines with input for katakana, kanji and another variant. Sorry, if the names are not exact, but was a long time ago. But imagine implementing a soundX function for something like thai :) ironically enough thai is a tone based language. 5 tones. High, low, rising, falling and mid tones. The first trick is to find out what constitutes a thai word :) thai is written without spaces. A lot of rules to figure out what a word is :) I did a neat trick some years ago when learning thai. I used MS word and vb script to do word breaks for me. So easy in word to iterate over each word and print it out. As a word processor that supports a language it needs these rules, and they do it well.
                                            I know I digress from Pythonista specific things now. But sometimes these simple tools/ideas can help.

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