Skip to content

Instantly share code, notes, and snippets.

@ColdGrub1384
Last active June 3, 2020 23:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ColdGrub1384/378e40b2296223217aa27c275939c8b3 to your computer and use it in GitHub Desktop.
Save ColdGrub1384/378e40b2296223217aa27c275939c8b3 to your computer and use it in GitHub Desktop.
UIKit views on PytoUI

objc_view

This is a small module for building pyto_ui views with UIKit. Here is an example with UIDatePicker.

import objc_view as ov
from UIKit import UIDatePicker
from datetime import datetime
from typing import Callable
import pyto_ui as ui

PICKER_MODE_TIME = 0
PICKER_MODE_DATE = 1
PICKER_MODE_DATE_AND_TIME = 2
PICKER_MODE_COUNTDOWN_TIMER = 3

class DatePicker(ov.WrapperView): # Subclass `WrapperView`
    objc_class = UIDatePicker # Specify the UIKit class

    def __init__(self, mode):
        self.mode = mode
        super().__init__()

    def get_date(self) -> datetime:
        date = str(self.objc_view.date) # Get the description of an Objective-C object
        obj = datetime.strptime(date, "%Y-%m-%d %H:%M:%S %z")
        return obj

    def on_change(self, func: Callable):
        
        # Use `Target` as target and use `Selector` to make a selector.
        self.objc_view.addTarget(
            ov.Target, action=ov.Selector(func), forControlEvents=4096
        )

    def configure_view(self, view):
        view.datePickerMode = self.mode
        
        
date_picker = DatePicker(PICKER_MODE_DATE)
date_picker.background_color = ui.COLOR_SYSTEM_BACKGROUND

def on_change():
    date_picker.title = str(date_picker.get_date())

date_picker.on_change(on_change)

# Show the view as any `pyto_ui` view.
ui.show_view(date_picker, ui.PRESENTATION_MODE_SHEET)

date = date_picker.get_date()
print(date)
"""
A module for using UIViews with pyto_ui.
"""
from UIKit import *
from rubicon.objc import ObjCClass, ObjCInstance
from mainthread import mainthread
from time import sleep
from pyto import PySelector, SelectorTarget
from typing import Callable
import pyto_ui as ui
def Selector(func: Callable) -> ObjCInstance:
"""
Returns an Objective-C selector from the given function.
Doesn't work propertly for class / object methods.
Use this with a global function.
:rtype: ObjCInstance
"""
def annotated() -> None:
func()
return PySelector.makeSelector(annotated)
Target = SelectorTarget.shared
"""
The target responding to selectors created by Selector.
"""
class WrapperView(ui.View):
"""
A view wrapping an UIKit view.
"""
objc_class = UIView
"""
The UIKit class of the view.
To access UIKit classes, import the UIKit module.
"""
__setup_finished__ = False
@property
def objc_view(self) -> UIView:
"""
Returns the Objective-C UIKit View.
:rtype: UIView
"""
return self.__py_view__.managed
def __init__(self):
super().__init__()
self._make_view()
while not self.__setup_finished__:
# Wait because _make_view is executed async
# in the main thread
sleep(0.2)
self.__configure_view__(self.__py_view__.managed)
@mainthread
def _make_view(self):
self.__py_view__.managed = self.objc_class.new()
self.__setup_finished__ = True
@mainthread
def __configure_view__(self, view):
self.configure_view(view)
def configure_view(self, view: UIView):
"""
Configure the view after being initialized.
:param view: The created UIKit view.
"""
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment