• Very clean and Pythonic; I approve.

  • @omz and @Cethric thanks for the help. It seems to work.

  • # In Pythonista version 3.0 (300005) on iOS 9.2.1... from objc_util import ObjCClass print('\n'.join(ObjCClass.get_names('OM')))
  • I can confirm that this is still a bug on iOS 9.3 beta, where all the web dialogs were redone.

  • It looks like you have a script of your own called ctypes.py in a "temp" folder. Naming your scripts like built-in modules is never a good idea, try renaming it to something like ctypes_tests.py (and restart Pythonista if that doesn't help right away).

  • Replying so people see this. I found a way to stop the crashing and (fun stuff) found out how to get the custom view controller that is created with each view. This allows you to use the view controller's methods to present oth view controllers!

    # coding: utf-8 from objc_util import * import ctypes import ui SUIViewController = ObjCClass('SUIViewController') UIAlertController = ObjCClass('UIAlertController') UIAlertAction = ObjCClass('UIAlertAction') def ok_pressed(sender): print 'OK pressed' alert = UIAlertController.alertControllerWithTitle_message_preferredStyle_(ns('My Alert'), ns('My Message'), 1) alert_action_block = ObjCBlock(ok_pressed, None, [c_void_p]) default_action = UIAlertAction.actionWithTitle_style_handler_(ns('OK'), 0, None) alert.addAction_(default_action) ##rvc.presentModalViewController_animated_(alert, True) ## Stop Crashes retain_global(alert_action_block) def button_tapped(sender): super_view = sender.superview super_view_pntr = ObjCInstance(super_view) vc = SUIViewController.viewControllerForView_(super_view_pntr) vc.presentModalViewController_animated_(alert, True) view = ui.View(frame=(0,0,500,500)) view.name = 'Demo' view.background_color = 'white' button = ui.Button(title='Tap me!') button.center = (view.width * 0.5, view.height * 0.5) button.flex = 'LRTB' button.action = button_tapped view.add_subview(button) view.present('sheet')

    Hope you find this useful,
    B

  • if you change the retainme line so that it is stored in a built in package, it will ensure it does not get gc'd when rerunning. As is, when you click play again, it results in a crash, because the objc object still exists, but the callback doesn't.

    ui._retain_me = tabBar_didSelectItem_
  • Wow. That's really neat. Good job!

  • @dgelessus you're right. sorry! Next time, I'll copy the code!

    I changed my code based on your answer: I created a third pyui file for the root view and pushed the root view via code to the navigation view rather than in the UI Builder and I set the button_right_items in the code that loads the root view.

    That worked!

    Here's exactly what I did in case someone is stuck with the same very basic problem:

    I created a script file with a UI file. They share the same filename (say NavView.py and NavView.pyui). In The pyui file, all I did was set the Custom Class View to ui.NavView. In its corresponding py-file, i created class NavView(ui.View). Also, I created two stand alone UI files for designing the root view and the sub view.

    This is the class:

    # coding: utf-8 import ui class NavView(ui.View): def __init__(self): # Load the default view that's placed inside the Navigation View. # This root view has its own pyui file (here: RootView.pyui). # That makes it easier to design the root view. root = ui.load_view('RootView.pyui') # Set the titlebar text of the Navigation View when the root view is loaded root.name = 'Root View' # Specify the visible buttons in the navigation view titlebar when the root view is visible. root.right_button_items = [ui.ButtonItem(action=self.openSubView, image=ui.Image.named('ionicons-close-24'))] # Create the Navigation View with the root view preloaded self.v = ui.NavigationView(root) self.v.present('sheet') def openSubView(self,sender): # Load the sub view thats loaded when the defined button in the Navigation View is pressed while the root view is loaded sub = ui.load_view('SubView.pyui') # This text will be displayed as the Navigation View's titlebar text sub.name = 'Sub View' # Display the sub view instead of the root view self.v.push_view(sub) # Call the class NavView()

    If you have any suggestion on how to improve the code, I'd love to hear it!

    The above code works great as long as I don't actually want to do anything with the code. I'm not getting it. Did I miss any kind of tutorial or documentation?

    Say I have a button in one of the sub views. How do I make the button (with action set to buttonFunction) do anything? def buttonFunction(sender) below the class doesn't work. def buttonFunction(self, sender) inside the class doesn't work either. And it doesn't matter wether every view (not just the Navigation View Container pyui) or just the top level pyui that has the Navigation View in it has its custom view class set to ui.NavView or not.

    I'm really confused since I can't find anything like a introduction to Pythonista UI Designer...

  • I liked @briarfox's runpy idea best. Here is a working example:

    import os, runpy path = os.path.join(os.path.dirname(__file__), 'games') python_scripts = [f for f in os.listdir(path) if f.lower().endswith('.py')] for i, ps in enumerate(python_scripts): print('{:>3} - {}'.format(i, ps[:-3])) while True: selection = raw_input('Which game do you want to run: ') if selection.lower() in ('', 'q', 'quit'): # enter nothing to quit break try: runpy.run_path(os.path.join(path, python_scripts[int(selection)])) except (IndexError, ValueError): print('Please pick one of the numbers above!!')
Internal error.

Oops! Looks like something went wrong!