0

I am working on a musical instrument type app. It uses a keyboard like set of UIButtons to trigger playing a musical note when touchDown occurs. The note stops playing based on touchUpInside or touchUpOutside events.

Everything works as expected except when attempting to play multiple notes. The touchDown events work, but touchUpInside event is not sent when a button is released as expected when another button continues to be touched. The touchUpInside is sent to all the buttons when all the buttons are released.

It appears to buffer other touch events until the button being held is released. If a button is released and another pressed, the touchDown and touchUpInside events are not sent to that button until all the other buttons are released. Then the touchUpInside events are sent to the first buttons and the subsequent events are triggered.

This flow has been traced through the code for the IBActions for the events. I have enabled multitouch. I have tried allowing multiple gesture recognizers. Nothing seems to affect this behavior.

There is no real code to share as the buttons and events were built using Interface Builder - Storyboard.

Is there something holding up the processing of events pending the release of previous touch events?

Any suggestions would be appreciated? I have searched for other similar questions but could not find this issue.

Thank you!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
McInvale
  • 158
  • 1
  • 10
  • 1
    Do not use buttons for this. Use custom views, track touches began and touches ended yourself. – matt Apr 23 '17 at 04:28
  • @matt, is there a reason or explanation for your suggestion? Do you know why the issue is happening for the touchDown and touchUpInside events for UIButtons? – McInvale Apr 23 '17 at 04:36
  • 1
    You need to think about how iOS (and likely, *any* OS) handles "touches" and "button clicks". (For the most part, they are the same.) You don't [generally] do "multi-touch" to open an app, type on a [physical or software] keyboard, etc. You do it one tap, touch, or mouse click at a time. What @matt says is correct - use a custom view (not even a custom button, as that inherits from NSControl) and write the touches began/end yourself. –  Apr 23 '17 at 10:20
  • @dfd, I appreciate your's and matt's comments. I understand about touches, gesture recognizers, and IBActions tied to events at a high level. My struggles and frustration with iOS programming and Xcode is understanding when to use IB functionality, high level code like gesture recognizers or low level code (touches). Any suggestions on where to research low level details and compare high level vs. low level functionality? Specifically, in this case touch events vs. IBActions. – McInvale Apr 23 '17 at 18:55
  • @matt, see my previous comment. I could not tag you also in it. Does one of your books contain a comparison of the use of low level coding vs. high level coding and when it is best to use one or the other? This is not the first time with this project that I have had to recode when I run into a dead end using IB and switch to hard coding. IB Layout constraints is one example. I have also have had to switch from UIButtons to custom views for another functionality. Trial and error is frustrating. Stackoverflow and Google should not be the resource of choice for Xcode development... – McInvale Apr 23 '17 at 19:25
  • That's difficult to answer, as both instinct and experience come into play. (And I sympathize with you while knowing at the same time that doesn't help.) My best explanation is that use "high level" first - Apple does try to make it work and improves tools like IB every year it seems - while learning *both* the (a) "low level" - we used to call it "command line" or maybe "Assembler code" back in the day - behind it, along with the (b) weaknesses of the high level tools. In your case at the low level is simply that an array of buttons will fire one at a time, so you need to "roll your own". –  Apr 23 '17 at 19:41
  • 1
    Basically you're asking me to repeat what I already said and what dfd already said. NSControl and control events and when they get sent is a very high-level analysis and reporting of touches. You _hoped_ touchDown and touchUpInside would be sent when you wanted them for this odd multitouch situation (touching multiple buttons at the same time), but they weren't. You said "any suggestions would be appreciated" and you got suggestions. Buttons work the way they work. It isn't what you want. So don't use them. No big deal. – matt Apr 23 '17 at 19:47
  • 1
    Regards to your comment to Matt, two points in agreement. (1) A weakness of IB that crops up is that it's a design -time tool and things like auto layout may have run-time needs like orientation changes, animations, etc. While this may not be the *exact* issue you faced, a deeper understanding of layout, view events, etc., *always* help. (2) I've programmed professionally since 1984, but I only dabbled with Xcode since 2004. Back then it was two very separate apps, coding only in Objective-C. Believe me, the resources out there are about *two* levels better, and I'm sure improving every year. –  Apr 23 '17 at 19:57
  • @dfd, I appreciate your feedback! I also have been programming a long time. I have seen programming with punched cards, assembler on multiple operating systems, DOS, Windows 3.11, BSD Unix, and numerous languages. Developer tools have improved and continue to improve over the last 40 years and continue to improve. Thank you for your assistance! – McInvale Apr 23 '17 at 20:42

1 Answers1

2

As your piano keys, use custom views, not UIButtons. You can probably most easily track the kind of touches you want to detect by attaching a UILongPressGestureRecognizer to each view. Or, at a lower level, you could simply detect touch events directly.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Based on your suggestion, I am recoding to use touches and eliminate the use of UIButtons for the keys. As I previously suggested, I have had to do the same for another functional part of the project. My frustration was not focused at you. I apologize for you having to repeat yourself. Thank you! – McInvale Apr 23 '17 at 20:16