How would I insert cells into a tableview? I have tried a few different ways, but I can't seem to figure it out. Could anyone point me to the correct way with code?
Forum Archive
Inserting Cells into Tableviews
Here is a very quick and rough example
# coding: utf-8
import ui
import dialogs
class source (object):
def __init__(self):
self.items = []
def tableview_number_of_rows(self, tv, s):
return len(self.items)
def tableview_cell_for_row(self, tv, s, r):
cell = ui.TableViewCell()
cell.text_label.text = self.items[r]
return cell
def add(self, sender):
item = dialogs.input_alert('Add item')
if not item == None:
self.items.append(item)
view.reload()
view = ui.TableView()
source = source()
view.right_button_items = [ui.ButtonItem(title='add', action=source.add)]
view.data_source = source
view.present()
@shaun-h thanks so much! I really appreciate it. I could not for the life of me figure it out.
@shaun-h I have been looking through your example, but I once I implemented it into my app's code, it won't show the changes on the table. Here is the code. Can you figure out why it won't work? My t why it won't work? My self.items variable IS being updated with the new filenames (yes there are files in the directory I am using), and my data_source is correctly binded with the tableview. I can't figure out why nothing will work.
@shaun-h
class browser_source (object):
def __init__(self):
self.items = []
def tableview_number_of_sections(self, tableview):
# Return the number of sections (defaults to 1)
return 0
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.
return 'illuminati confirmed'
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
def tableview_number_of_rows(self, tv, s):
return len(self.items)
def tableview_cell_for_row(self, tv, s, r):
cell = ui.TableViewCell()
cell.text_label.text = self.items[r]
return cell
def open_browser(self, sender):
for current in os.listdir("notes"):
if ".nly" in current:
self.items.append(current
print self.items
print sender.superview["browser"]["tableview1"].reload()
The print statements were for checking if it actually was reloading the tableview, and it should be. But when I remove the print statements, and actually let the tableview reload, it doesn't do anything.
Yes there is more code. I will post the full thing in just a second.
@shaun-h here is the full code:
# coding: utf-8
import ui
import xml.etree.ElementTree as eltree
import notification
import os
stored_table = None
class browser_source (object):
def __init__(self):
self.items = []
def tableview_number_of_sections(self, tableview):
# Return the number of sections (defaults to 1)
return 0
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.
return 'illuminati confirmed'
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
def tableview_number_of_rows(self, tv, s):
return len(self.items)
def tableview_cell_for_row(self, tv, s, r):
cell = ui.TableViewCell()
cell.text_label.text = self.items[r]
return cell
def open_browser(self, sender):
for current in os.listdir("notes"):
if ".nly" in current:
self.items.append(current
print self.items
print sender.superview["browser"]["tableview1"].reload()
# Then pop the browser into view.
def animation():
sender.superview["browser"].frame = (14,164,393,300)
ui.animate(animation, duration=0.4)
class notepad_del (object):
def textview_should_begin_editing(self, textview):
return True
def textview_did_begin_editing(self, textview):
pass
def textview_did_end_editing(self, textview):
pass
def textview_should_change(self, textview, range, replacement):
return True
def textview_did_change(self, textview):
textview.superview["character_count"].text = str(len(textview.text))
def textview_did_change_selection(self, textview):
pass
def save_file(sender):
pass
def open_browser(sender):
browser_source().open_browser(sender)
def browser_open_file():
pass
def browser_edit_file():
pass
v = ui.load_view()
v.present('sheet')
notepad = v["pad"]
notepad.delegate = notepad_del()
# Load the starting note file.
startingNote = eltree.parse("notes/startup.nly")
startingTitle = startingNote.find("title").text
startingText = startingNote.find("body").text
apptitle = v["apptitle"]
apptitle.text = startingTitle
notepad.text = startingText
v["character_count"].text = str(len(notepad.text))
browser_table = v["browser"]["tableview1"]
browser_table.data_source = browser_source()
stored_table = browser_table
You seem to creating new broswer_source objects, when I think you want to pass an instance around. your open_browser callback creates a new instance, then calls the open_browser function on the instance.....which is NOT the table's data source, so of course anything you do on the temporary instance will be lost. consider finding the table datasource from sender, (i.e sender.superview['tableview1'], or whatever is needed since we don't have your pyui) or instantiating one data source as a global and referring to that inside open_browser.
@JonB here is the UI file as a .json format. Just load it in Pythonista as .pyui with the full code I posted earlier. I need to figure this out.
[
{
"class" : "View",
"attributes" : {
"name" : "Notably",
"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)",
"enabled" : true,
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"flex" : ""
},
"frame" : "{{0, 0}, {420, 600}}",
"selected" : false,
"nodes" : [
{
"class" : "View",
"attributes" : {
"class" : "View",
"name" : "toolbar",
"uuid" : "CFA2AE4D-CDBA-4E57-B769-C83F495ADA4B",
"frame" : "{{135, 250}, {100, 100}}",
"background_color" : "RGBA(0.239130,0.492754,1.000000,1.000000)"
},
"frame" : "{{0, 0}, {420, 66}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "Button",
"attributes" : {
"font_size" : 15,
"tint_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"uuid" : "5C3A68DE-0E18-4468-B352-F88DEE241F79",
"name" : "savebutton",
"corner_radius" : 7,
"border_width" : 0,
"action" : "save_file",
"class" : "Button",
"frame" : "{{145, 284}, {80, 32}}",
"background_color" : "RGBA(0.221493,0.430681,0.849057,1.000000)",
"title" : "Save"
},
"frame" : "{{339, 13}, {68, 40}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "TextView",
"attributes" : {
"background_color" : "RGBA(0.969340,0.969340,0.969340,1.000000)",
"alignment" : "left",
"autocorrection_type" : "no",
"font_size" : 18,
"font_name" : "AnonymousPro-Bold",
"frame" : "{{85, 200}, {200, 200}}",
"flex" : "WH",
"text" : "",
"name" : "pad",
"spellchecking_type" : "default",
"editable" : true,
"uuid" : "19C1F272-015F-4F77-97E4-64EAF035DFE7",
"class" : "TextView"
},
"frame" : "{{0, 96}, {420, 504}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "View",
"attributes" : {
"class" : "View",
"name" : "view1",
"uuid" : "9F08346C-279D-41D5-B64A-9CECE5FA7271",
"frame" : "{{135, 250}, {100, 100}}",
"background_color" : "RGBA(0.237285,0.438064,0.839623,1.000000)"
},
"frame" : "{{0, 66}, {420, 30}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "Label",
"attributes" : {
"font_size" : 18,
"text" : "",
"font_name" : "<System>",
"name" : "character_count",
"text_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"class" : "Label",
"alignment" : "left",
"frame" : "{{110, 284}, {150, 32}}",
"uuid" : "558EC31A-DDC5-420C-BAEB-9E53F8778003"
},
"frame" : "{{4, 70}, {209, 22}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "View",
"attributes" : {
"class" : "View",
"name" : "browser",
"uuid" : "74B291E2-2843-4BB1-B2A4-EAA243FC12C4",
"frame" : "{{160, 250}, {100, 100}}"
},
"frame" : "{{-393, 164}, {393, 300}}",
"selected" : false,
"nodes" : [
{
"class" : "View",
"attributes" : {
"class" : "View",
"name" : "browsertoolbar",
"uuid" : "8E3922BA-83C8-441C-B884-57ED537CD314",
"frame" : "{{147, 101}, {100, 100}}",
"background_color" : "RGBA(1.000000,0.369565,0.369565,1.000000)"
},
"frame" : "{{0, 0}, {393, 46}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "Label",
"attributes" : {
"font_size" : 18,
"text" : "Browsd for iPad.",
"font_name" : "AvenirNext-Bold",
"name" : "label1",
"text_color" : "RGBA(0.764151,0.282404,0.282404,1.000000)",
"class" : "Label",
"alignment" : "left",
"frame" : "{{122, 135}, {150, 32}}",
"uuid" : "CFF0545E-FD64-4F3C-861A-4C776C74FD28"
},
"frame" : "{{12, 6}, {150, 34}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "TableView",
"attributes" : {
"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"frame" : "{{97, 50}, {200, 200}}",
"data_source_number_of_lines" : 1,
"row_height" : 38,
"tint_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"flex" : "WH",
"data_source_action" : "browser_open_file",
"data_source_items" : "",
"data_source_delete_enabled" : true,
"data_source_edit_action" : "browser_edit_file",
"name" : "tableview1",
"uuid" : "E8DA11CE-3F2E-459E-A8EE-8CF03CBBE08F",
"data_source_font_size" : 20,
"class" : "TableView"
},
"frame" : "{{0, 46}, {393, 254}}",
"selected" : true,
"nodes" : [
]
}
]
},
{
"class" : "TextField",
"attributes" : {
"alignment" : "left",
"autocorrection_type" : "default",
"font_size" : 19,
"font_name" : "<System>",
"placeholder" : "Enter file title.",
"frame" : "{{110, 284}, {200, 32}}",
"text" : "Loading app...",
"text_color" : "RGBA(0.245283,0.245283,0.245283,1.000000)",
"name" : "apptitle",
"spellchecking_type" : "default",
"uuid" : "3CB32582-5B56-4117-A1AD-2958DC122FF0",
"class" : "TextField"
},
"frame" : "{{13, 13}, {200, 41}}",
"selected" : false,
"nodes" : [
]
},
{
"class" : "Button",
"attributes" : {
"font_size" : 15,
"tint_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"title" : "Browse",
"name" : "createbutton",
"corner_radius" : 7,
"border_width" : 0,
"action" : "open_browser",
"class" : "Button",
"frame" : "{{145, 284}, {80, 32}}",
"background_color" : "RGBA(0.221493,0.430681,0.849057,1.000000)",
"uuid" : "5C3A68DE-0E18-4468-B352-F88DEE241F79"
},
"frame" : "{{256, 13}, {75, 40}}",
"selected" : true,
"nodes" : [
]
}
]
}
]
Did you read the entire response? Without looking at your pyui it is clear that your table data source is not the same instance the one which gets the open_browser() called.
Can you change
def tableview_number_of_sections(self, tableview):
# Return the number of sections (defaults to 1)
return 0
To return 1 instead of 0 I think that might cause some issues
@JonB oh sorry, I didn't. I feel like a flipping idiot since that was the problem. Thanks! I fixed the issue. Very helpful.
@shaun-h thanks for helping me through it. I'm extremely grateful for the help.