I want to create an auto-complete TextField.
I mean - when you type something in the field and see a prompt list below. The prompt list is an array with possible values. The best way to explain it show a similar picture.
I already have some experience in Pythonista 3 but it was not UI programming experience.
I understand this is complex and that maybe I should use an additional View and Delegate mechanism but I don't have any idea how to start. I have already spent several days in Google looking for a solution, but I can't, in the context of Pythonista.
Has anybody done this? Or could someone provide useful links for reading?
A drop-down list can be created in Pythonista using a TableView. TableViews are really just single-column lists, they’re not just for tables.
So the steps would be:
You can hide any view by setting its .hidden
property to True
.
You can do things when typing starts in a TextField by creating a delegate object that implements textfield_did_change
.
You set a TableView to have a list of items by giving the TableView a data_source
, probably an implementation of ui.ListDataSource
. Whenever the items
property on the data source changes, the list of options will also automatically change.
You can react to the user choosing an option from the TableView by setting an action
on the TableView’s delegate
.
The documentation for TableView, TextField, ListDataSource, delegates, and actions, can be found at Pythonista’s Native GUI for iOS documentation.
Here is a basic example:
# documentation at http://omz-software.com/pythonista/docs/ios/ui.html
import ui
# the phoneField delegate will respond whenever there is typing
# the delegate object will combine phoneField delegate, tableview delegate, and data source, so that it can share data
class AutoCompleter(ui.ListDataSource):
def textfield_did_change(self, textfield):
dropDown.hidden = False
# an arbitrary list of autocomplete options
# you will have a function that creates this list
options = [textfield.text + x for x in textfield.text]
# setting the items property automatically updates the list
self.items = options
# size the dropdown for up to five options
dropDown.height = min(dropDown.row_height * len(options), 5*dropDown.row_height)
def textfield_did_end_editing(self, textfield):
#done editing, so hide and clear the dropdown
dropDown.hidden = True
self.items = []
# this is also where you might act on the entered data
pass
def optionWasSelected(self, sender):
phoneField.text = self.items[self.selected_row]
phoneField.end_editing()
autocompleter = AutoCompleter(items=[])
autocompleter.action = autocompleter.optionWasSelected
# a TextField for phone number input
phoneField = ui.TextField()
phoneField.delegate = autocompleter
phoneField.keyboard_type = ui.KEYBOARD_PHONE_PAD
phoneField.clear_button_mode = 'while_editing'
# the drop-down menu is basically a list of items, which in Pythonista is a TableView
dropDown = ui.TableView()
dropDown.delegate = autocompleter
dropDown.data_source = autocompleter
# hide the dropdown until typing starts
dropDown.hidden = True
# create interface
mainView = ui.View()
mainView.add_subview(phoneField)
mainView.add_subview(dropDown)
# present the interface before aligning fields, so as to have the window size available
mainView.present()
# center text field
phoneField.width = mainView.width*.67
phoneField.height = 40
phoneField.x = mainView.width/2 - phoneField.width/2
phoneField.y = mainView.height/3 - phoneField.height/2
# align the dropdown with the phoneField
dropDown.x = phoneField.x
dropDown.y = phoneField.y + phoneField.height
dropDown.width = phoneField.width
dropDown.row_height = phoneField.height
On my iPhone, this code creates an interface that looks like this: