Skip to content

Instantly share code, notes, and snippets.

@ColdGrub1384 ColdGrub1384/README.md

Last active Jun 3, 2020
Embed
What would you like to do?
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
You can’t perform that action at this time.