Forum Archive

Initialize search field of a UIDocumentPickerViewController?

cvp

Question for big guru(s): is it possible to initialize the search field of a UIDocumentPickerViewController?

Actually, I do it via copy (in script) / paste (manual)

JonB

You might take a look at my viewbrowser, and have it display right after presenting the picker. Then you can find the search bar in the view heirarchy.

Or play around with dir(), or my objcbrowser to find if it exposes the searchbar in the view controller.

cvp

@JonB Thanks to try to help me.
I had tried dir, subview, .... on the ViewContoller

    #print(dir(UIDocumentPickerViewController.navigationItem()))
    #v = UIDocumentPickerViewController.navigationItem().searchController()
    #print(dir(v))#.navigationBar()))

but without success
I just installed your both tools but I don't understand how to use them.
Sorry for my incompetence 😢

JonB

iirc UIsearchController has a searchBar property, which returns a UiSearchBar, which then has a .text property that should be settable, perhaps on_main_thread to be safe.

cvp

@JonB

    v = UIDocumentPickerViewController.navigationItem().searchController()
    print(dir(v))

Gives

['__bool__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

I had tried that but no searchBar

Edit:

    v = UIDocumentPickerViewController.navigationItem().searchController()

Is None

cvp

@JonB If you have time to spend, this is my script. Anyway, thanks a lot as usual for your advices.

import ui
from objc_util import *
import time

#===================== delegate of UIDocumentPickerViewController: begin
def documentPickerWasCancelled_(_self, _cmd, _controller):
    #print('documentPickerWasCancelled_')
    UIDocumentPickerViewController = ObjCInstance(_controller)
    UIDocumentPickerViewController.uiview.close()
    if UIDocumentPickerViewController.callback:
        UIDocumentPickerViewController.callback('canceled')

def documentPicker_didPickDocumentsAtURLs_(_self, _cmd, _controller, _urls):
    #print('documentPicker_didPickDocumentsAtURLs_')
    UIDocumentPickerViewController = ObjCInstance(_controller)
    UIDocumentPickerViewController.uiview.close()
    if UIDocumentPickerViewController.callback:
        urls = ObjCInstance(_urls)
        UIDocumentPickerViewController.callback(str(urls[0]))

methods = [documentPicker_didPickDocumentsAtURLs_,documentPickerWasCancelled_]
protocols = ['UIDocumentPickerDelegate']
try:
        MyUIDocumentPickerViewControllerDelegate = ObjCClass('MyUIDocumentPickerViewControllerDelegate')
except:
    MyUIDocumentPickerViewControllerDelegate = create_objc_class('MyUIDocumentPickerViewControllerDelegate', methods=methods, protocols=protocols)
#===================== delegate of UIDocumentPickerViewController: end

@on_main_thread 
def MyPickDocument(w, h, mode='sheet', popover_location=None, callback=None):
    # view needed for picker
    uiview = ui.View()
    uiview.frame = (0,0,w,h)
    if mode == 'sheet':
        uiview.present('sheet',hide_title_bar=True)
    elif mode == 'popover':
        if popover_location:
            uiview.present('popover', hide_title_bar=True, popover_location=popover_location)
        else:
            return
    else:
        return

    UIDocumentPickerMode = 0    # 0 = UIDocumentPickerModeImport
                                                        # this mode allows a search field
    UIDocumentPickerViewController = ObjCClass('UIDocumentPickerViewController').alloc().initWithDocumentTypes_inMode_(['public.item'],UIDocumentPickerMode)

    objc_uiview = ObjCInstance(uiview)
    SUIViewController = ObjCClass('SUIViewController')
    vc = SUIViewController.viewControllerForView_(objc_uiview)  

    UIDocumentPickerViewController.setModalPresentationStyle_(3) #currentContext

    # Use new delegate class:
    delegate = MyUIDocumentPickerViewControllerDelegate.alloc().init()
    UIDocumentPickerViewController.delegate = delegate  
    UIDocumentPickerViewController.callback = callback  # used by delegate
    UIDocumentPickerViewController.uiview   = uiview        # used by delegate
    #print(dir(UIDocumentPickerViewController))
    vc.presentViewController_animated_completion_(UIDocumentPickerViewController, True, None)



    #print(dir(UIDocumentPickerViewController))#.navigationItem()))
    #v = UIDocumentPickerViewController.navigationItem().searchController()
    #print(v)
    #print(dir(v))
    #print(dir(v))#.navigationBar()))
    #print(v)
    #v.searchBar.setText_('ttt')


def main():
        # demo code
        def callback(param):
            # you could check if file save at hoped place...
            print(param)
        MyPickDocument(600,500,callback=callback)
        #MyPickDocument(600,500, mode ='popover', popover_location=(mv.width-40,60))

if __name__ == '__main__':
    main()
JonB

I'll give it a try - though I managed to erase my entire pythonista install, so have to reinstall my various wrench scripts etc.

JonB

it turns out that, for security reasons, the doc picker is actually a remote view, running in another process. looking into whether we can manually generate touch events...

cvp

@JonB Ok, thanks a lot to have spent time for this problem.

cvp

@JonB I still wanted some tries after the view has been presented but my code

    def handler(_cmd):
        print('here')
    handler_block = ObjCBlock(handler, restype=None, argtypes=[c_void_p])
    vc.presentViewController_animated_completion_(UIDocumentPickerViewController, True, handler_block)

gives an error

Fatal Python error: Bus error

Thread 0x000000016f60f000 (most recent call first):
JonB

Be sure to define handler, and handler_block someplace where its scope won't expire... i.e place those defs outside of MyPickDocument, not inside. alternatively, you need to retain_global

cvp

@JonB Thanks, error disappears. have you ever been told that you are a magician? 😀

cvp

@JonB Tried, and the only action I can do is changing text color

    UIDocumentPickerViewController.view().setTintColor_(ObjCClass('UIColor').colorWithRed_green_blue_alpha_(1.0,0.0,0.0,1.0))

JonB

there is a small chance that you can create a UITouchEvent, and send that to the _UISizeTrackingView or whatever it is called (thats the one that responds to hitTest_withEvent).

cvp

@JonB Thanks for still thinking about this topic but it really becomes too complicated for me and I think I'll stop my search because it is not vital and I spend too much time