Hi, i tried to use objc UIViewController to get key press with text field, but the problem is, if i press left arrow key first, and then press right arrow key, the right arrow key’s CustomViewController_pressesBegan_withEvent_ will not triggered, pls help?
Forum Archive
Check multi-keys press
i tried it before, but thank for your help :D it does the same result
@yaley said
if i press left arrow key first, and then press right arrow key
I guess you did not release the first press. Then perhaps you could intercept pressesChanged(_:with:)
@yaley ok. How about using pygame module? It might work :
import pygame
screen = pygame.display.set_mode((0,0,320,320))
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN or event.type == pygame.KEYUP:
if event.mod == pygame.KMOD_NONE:
print('No modifier keys were in a pressed state when this '
'event occurred.')
else:
if event.mod & pygame.KMOD_LSHIFT:
print('Left shift was in a pressed state when this event '
'occurred.')
if event.mod & pygame.KMOD_RSHIFT:
print('Right shift was in a pressed state when this event '
'occurred.')
if event.mod & pygame.KMOD_SHIFT:
print('Left shift or right shift or both were in a '
'pressed state when this event occurred.')
@DOGGY as explained here pygame is not Pure PyThon thus does not work in Pythonista
@cvp my code is still not working
def CustomViewController_pressesBegan_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].key().keyCode()
activeKeys[keyCode] = True
def CustomViewController_pressesEnded_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].key().keyCode()
activeKeys[keyCode] = False
def CustomViewController_pressesChanged_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].keyCode()
activeKeys[keyCode] = False
@yaley why do you set your activeKeys as False in changed?
@yaley Yes, sorry, as @cvp and my tries, using pygame module is not possible in Pythonista because Pythonista doesn’t have pygame Stash also cannot
@DOGGY It’s ok :)
@cvp oops that’s my wrong, but after changing it to True, it’s still not working, everything turns True, let me see the documentation carefully again.
After the key changed, the activeKey turns True, but then it will forever True, until next keyup
@yaley don't forget that presses is a kind of array with eventually multiple keys thus perhaps not only check [0]
@YaleY that would be a hard one…..
@cvp so what should i do now???? Can you show me the code with successful running?
@yaley said
Can you show me the code with successful running?
Ho no, you are further than me. I only try to think about it.
When you press the right arrow, your first key is still pressed?
@cvp yes, but the problem is when the second press joined CustomViewController_pressesChanged_withEvent_() didnt run about it
@cvp You’re method is correct, just i am stupid, i typed wrongly, i set the variable to True in the pressesEnded def
XD
@yaley right, just tested
Wait no, why??? Why my first test is correct and then the second test is not working?????
@yaley for me, changed not called
If you change something in a created class, restart Pythonista
@cvp here’s my code, I’ve tried to restart Pythonista
def CustomViewController_pressesBegan_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].key().keyCode()
activeKeys[keyCode] = True
def CustomViewController_pressesEnded_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].key().keyCode()
activeKeys[keyCode] = False
def CustomViewController_pressesChanged_withEvent_(_self, _cmd, _presses, event):
global activeKeys
presses = ObjCInstance(_presses).allObjects()
keyCode = presses[0].keyCode()
activeKeys[keyCode] = True
@yaley you should add some print in each method to check if called
@yaley said
keyCode = presses[0].keyCode()
Key() missing in changed
@yaley only began is called once with left arrow, second with right arrow
Thus, forget changed, and all is ok because two keys imply 2 calls to began
@cvp thanks it solved!!!
@cvp looks like i found the problem, if in the changed def, i set activeKeys[keyCode] = presses[0].key().keyCode() it doesn’t work, but if i set activeKeys[keyCode] = presses[0].keyCode() then it works :)
@yaley sorry, perhaps I (or my eyes) become too old, but I don't see the difference
@cvp no it’s my wrong again xD They’re absolutely no difference before, lol
@cvp I’ve already changed it, read it again :D The difference is [0].key().keyCode() and [0].keyCode()
Wait, um, after i added print() the pressesChange is not activating
@yaley ok. And did you trace, sure that changed def is called?
Sorry: was typing while your previous post was coming
@cvp i dont think that that def was called :(
@yaley but do you really need it? The doc says it is called if you change something in your key press, like force. If you know which key is down and up, and when, you have all you need, haven't you?
Yep! Maybe…. No need!
@cvp But the main problem is just when arrow keys will happen, just like umm i give you an example:
I am detecting keys with ui.Textfield() And now i start pressing left arrow key. So in the input it goes left ( the selection bar ), but if the right arrow keys joined the right arrow key, the selection bar of input still goes left.
And, also, can vi.View().get_key_commands() and ui.View().key_command(sender) detect keyup? if can, then i can make
@cvp can it?
@cvp but the main thing is it cannot handle 3 keys, i press space first, then press “a” key ( space key is still holding ), finally press”d” key but “D” key is not triggered and still moving left ( “A” for left, “D” for right )
@yaley sorry, was driving to France for some days, not able to answer
@yaley said
can it?
No idea
There are four methods you can implement:
https://developer.apple.com/documentation/uikit/uiresponder/1621134-pressesbegan?language=objc
You also have pressesEnded_withEvent_, and pressesChanged_withEvent_. Technically, pressesCancelled_withEvent_, but that's rare.
See
https://developer.apple.com/documentation/uikit/mac_catalyst/handling_key_presses_made_on_a_physical_keyboard?language=objc
You can inspect the modifiers:
UIKeyModifierAlphaShift 1<<16
A modifier flag that indicates the user pressed the Caps Lock key.
UIKeyModifierShift 1<<17
A modifier flag that indicates the user pressed the Shift key.
UIKeyModifierControl 1<<18
A modifier flag that indicates the user pressed the Control key.
UIKeyModifierAlternate 1<<19
A modifier flag that indicates the user pressed the Option key.
UIKeyModifierCommand 1<<20
A modifier flag that indicates the user pressed the Command key.
UIKeyModifierNumericPad 1<<21
A modifier flag that indicates the user pressed a key located on the numeric keypad
Also, to check for special characters, you would look at charactersIgnoringModifiers, and check for special strings from https://developer.apple.com/documentation/uikit/uikeycommand/input_strings_for_special_keys?language=objc
for example 'UIKeyInputRightArrow'
(Convert to str before comparing).
Technically, when looking at apple docs, in this case then consts are defined as NSString *, so the way you get the value is
ObjCInstance(c_void_p.in_dll(c, 'UIKeyInputRightArrow'))
But in this case, the NSString is simply equal to the constant name.
@JonB so….. what should i change?