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.


    How to implement swipe-to-delete in ListDataSource

    Editorial
    2
    3
    2675
    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.
    • wcaleb
      wcaleb last edited by

      I've looked at the documentation on this, but I'm having a hard time understanding how to implement a swipe-to-delete function in my Custom UI. I have the following set up and working:

      data = ui.ListDataSource(items)  
      view['tableview1'].data_source = data
      

      Where items is a list of files in my DropBox that the custom UI displays, along with some other buttons and features. I want to implement a function whereby when I swipe on a list item and delete it, it deletes it from DropBox, and I don't need help with the code to do the actual deleting in DropBox. But I don't know how/where to define the tableview_delete function described here:

      http://omz-software.com/editorial/docs/ios/ui.html#ui.TableView.data_source

      Do I need to include that entire class block in my script? My Python fu is still limited, so any help with the syntax for defining that function would be much appreciated.

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

        ListDataSource is pretty limited. It helps with simple cases, but it doesn't provide:

        • deleted item,
        • deleted item index,
        • ...

        Where to put your methods? Let's start from the beginning. TableView needs data_source to have a clue about data and it informs you about other actions like (de)selection via delegate. ListDataSource acts as data source and as delegate. There's no way to get info directly from TableView otherwise ListDataSource stops working. We have to check ListDataSource documentation if this object can inform us. And we are going to find:

        • action,
        • edit_action,
        • accessory_action,
        • selected_row,
        • tapped_accessory_row.

        Almost there. edit_action is our friend. But it receives ListDataSource object as sender thus we have no clue which one was deleted (if it was). Same method is called for edit / move. We have to keep list of items elsewhere too and compare ListDataSource.items with our items to check what happened. Something like this ...

        #coding: utf-8
        import ui
        
        items = [ 'a', 'b', 'c' ]
        
        def item_edited(sender):
        	removed = [x for x in items if x not in sender.items]
        	if len(removed) == 1:		
        		item = removed[0]
        		print 'Item \'%s\' removed' % item
        		items.remove(item)
        	else:
        		print 'Something\'s wrong, more than 1 removed item? With swipe to delete? Hmm ...'
        		
        def item_selected(sender):
        	row = sender.selected_row
        	if row != -1:
        		print 'Item selected at index %d (\'%s\')' % ( row, sender.items[row] )
        
        data_source = ui.ListDataSource(items)
        data_source.delete_enabled = True
        data_source.edit_action = item_edited
        data_source.action = item_selected
        
        view = ui.load_view()
        view['tableview1'].data_source = data_source
        view['tableview1'].delegate = data_source
        view.present('sheet')
        

        ListDataSource helps, is nice, but it's kinda limited (depends on your needs). If you reach limits, do it yourself.

        #coding: utf-8
        import ui
        
        class MyDataSource (object):
        	def __init__(self, items=[]):
        		self.items = list(items)
        		
        	def tableview_number_of_sections(self, tableview):
        		return 1
        
        	def tableview_number_of_rows(self, tableview, section):
        		return len(self.items)
        
        	def tableview_cell_for_row(self, tableview, section, row):
        		cell = ui.TableViewCell()
        		cell.text_label.text = self.items[row]
        		return cell
        
        	def tableview_can_delete(self, tableview, section, row):
        		return True
        
        	def tableview_delete(self, tableview, section, row):
        		print 'Item \'%s\' at %d row deleted' % ( self.items[row], row )
        		del self.items[row]
        
        class MyDelegate (object):
        	def tableview_title_for_delete_button(self, tableview, section, row):
        		return 'Trash It'	
        
        view = ui.load_view()
        view['tableview1'].data_source = MyDataSource(['a', 'b', 'c'])
        view['tableview1'].delegate = MyDelegate()
        view.present('sheet')
        
        1 Reply Last reply Reply Quote 0
        • wcaleb
          wcaleb last edited by

          Thanks for the helpful reply!

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