Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Date Picker w/ blank year
-
This post is deleted! -
@cvp thank you.
what I meant is to enter year 1604 in order to invalidate the year as the following image that I failed to embed:
-
-
@osamu Ok, I understand, I'll try to hide the year by a normal (ObjectiveC) picker. Back in some hours.
-
@osamu I'm still in progress...
-
@osamu ok, try this (hoping I had correctly understood, but not sure)
The view title will show the selected datefrom datetime import datetime import ui from objc_util import ObjCInstance,ObjCClass from math import pi,cos,sin #===================== delegate of UIPickerView: begin ===================== def pickerView_numberOfRowsInComponent_(self, cmd, picker_view, component): return(len(ObjCInstance(picker_view).data)) def numberOfComponentsInPickerView_(self, cmd, picker_view): return 1 def rowSize_forComponent_(self, cmd, picker_view, component): return ObjCInstance(picker_view).myRowWidth def pickerView_rowHeightForComponent_(self, cmd, picker_view, component): return ObjCInstance(picker_view).myRowHeight def pickerView_didSelectRow_inComponent_(self, cmd, picker_view, row, component): UIPickerView = ObjCInstance(picker_view) UIPickerView.selectedRow = row if UIPickerView.myDidSelectRow: UIPickerView.myDidSelectRow() return def pickerView_viewForRow_forComponent_reusingView_(self, cmd, picker_view, row, component,view_ptr): UIPickerView = ObjCInstance(picker_view) if view_ptr == None: #view = ObjCClass('UILabel').alloc().init() #view.setText_(UIPickerView.data[row]) uiview = ui.Label() uiview.alignment = ui.ALIGN_CENTER uiview.text_color = 'red' uiview.text = UIPickerView.data[row] view = ObjCInstance(uiview) view.setClipsToBounds_(True) if UIPickerView.horiz: a = pi/2 rot = CGAffineTransform(cos(a),-sin(a),sin(a),cos(a),0,0) view.setTransform_(rot, restype=None, argtypes=[CGAffineTransform]) else: view = ObjCInstance(view_ptr) return view.ptr methods = [ numberOfComponentsInPickerView_, pickerView_numberOfRowsInComponent_, rowSize_forComponent_, pickerView_rowHeightForComponent_, pickerView_didSelectRow_inComponent_, pickerView_viewForRow_forComponent_reusingView_] protocols = ['UIPickerViewDataSource', 'UIPickerViewDelegate'] UIPickerViewDataSourceAndDelegate = create_objc_class( 'UIPickerViewDataSourceAndDelegate', methods=methods, protocols=protocols) #===================== delegate of UIPickerView: end ======================= class MyUIPickerView(ui.View): def __init__(self, data, horiz=False,myRowHeight=100, myDidSelectRow=None, **kwargs): super().__init__(**kwargs) UIPickerView = ObjCClass('UIPickerView') self._picker_view = UIPickerView.alloc().initWithFrame_(ObjCInstance(self).bounds()).autorelease() ObjCInstance(self).addSubview_(self._picker_view) self.delegate_and_datasource = UIPickerViewDataSourceAndDelegate.alloc().init().autorelease() self._picker_view.delegate = self.delegate_and_datasource self._picker_view.dataSource = self.delegate_and_datasource self._picker_view.myRowWidth = self.width self._picker_view.myRowHeight = myRowHeight self._picker_view.myDidSelectRow = myDidSelectRow self._picker_view.data = data self._picker_view.horiz = horiz if horiz: a = -pi/2 rot = CGAffineTransform(cos(a),-sin(a),sin(a),cos(a),0,0) self._picker_view.setTransform_(rot, restype=None, argtypes=[CGAffineTransform]) def layout(self): self._picker_view.frame = ObjCInstance(self).bounds() v = ui.View() v.name = 'for @osamu' v.frame = (0,0,300,150) d = ui.DatePicker() d.frame = v.frame d.mode = ui.DATE_PICKER_MODE_DATE def d_action(sender): d_str = sender.date.strftime('%Y%m%d %H%M%S') v.name = d_str d.action = d_action v.add_subview(d) objc = ObjCInstance(d) back_ui_color = ObjCClass('UIColor').color(red=0.8, green=0.8, blue=0.8, alpha=1.0) objc.backgroundColor = back_ui_color years = ['2019','2020','2021','2022','----'] w = 100 def myDidSelectRow(): #print(pv._picker_view.selectedRow) year = years[pv._picker_view.selectedRow] if year == '----': year = '1604' d_str = year + d.date.strftime('%m%d %H%M%S') d.date = datetime. strptime(d_str, '%Y%m%d %H%M%S') v.name = d_str pv = MyUIPickerView(years, myRowHeight=32, myDidSelectRow=myDidSelectRow, frame=(d.width-w,0,w,d.height)) pv.background_color = 'lightgray' #pv.border_width = 1 #pv.border_color = 'blue' #pv.corner_radius = 5 v.add_subview(pv) hc = ObjCInstance(pv) hc.backgroundColor = back_ui_color v.present('sheet')
italicised text
-
@cvp Thank you very much indeed for spending time 🙏
This picker is the one that shows up when you enter birthday and other dates when using contacts app. I’m going to try your code. -
@osamu In this case, the ---- can't be selected but only shows a maximum date.
I think that we can also set this maximum date without all the code I wrote -
@osamu try this little script. You will not see the wanted "----" but after the now-date, day/month/years are grayed and not selectable with automatic return to today picker. I'm sure I'm not clear, thus try it.
import ui v = ui.View() v.name = 'for @osamu' v.frame = (0,0,300,150) d = ui.DatePicker() d.frame = v.frame d.mode = ui.DATE_PICKER_MODE_DATE v.add_subview(d) objc = ObjCInstance(d) nsDate = ObjCClass('NSDate').alloc().init() # initialized with now-date #print(dir(nsDate)) objc.setMaximumDate_(nsDate) v.present('sheet')
-
-
@cvp I tried the first version but Pythonista claimed create_objc_class() is missing. There may be some more. I guess I need to sneak into your library and steal them.
-
@osamu my error
from objc_util import *
-
@cvp I got it. Thank you.
-
@cvp This script initializes the year as 2019. If I set;
years = [str(y) for y in range(1605,datetime.now().year+1)] + ['----']
the initial year is set to 1605 and we’re far away from —— and recent years. Can we control this initial value? -
Have you tried reversing the list?
-
@JonB That’s a good idea 👍
-
@cvp one last question.
Can I set the initial year?
The following does not work.class MyUIPickerView(ui.View): def __init__(self, data, horiz=False,myRowHeight=100, myDidSelectRow=None, **kwargs): super().__init__(**kwargs) UIPickerView = ObjCClass('UIPickerView') self._picker_view = UIPickerView.alloc().initWithFrame_(ObjCInstance(self).bounds()).autorelease() ObjCInstance(self).addSubview_(self._picker_view) ... self._picker_view.selectedRow = XXX
Thanks in advance.
-
@osamu selectedRow is not an attribute of UIPickerView but is an user attribute set in the pickerView_didSelectRow_inComponent_ delegate, thus you can't set it.
I think we would need to use kind of
. . . self._picker_view.horiz = horiz xxx = 1 self._picker_view.selectRow_inComponent_animated_(xxx,0,True)
Tested, ok
-
@cvp Yes, it works. Thanks!