Semi-piano app touch troubles with UIButtons - iphone

I am working on a semi-piano app with a diffrent keyboard-layout then a usual one.
I created the view manually with UIButtons,
My problem was I that I didn't know how to slide from a UIButton to another,
I figured that out with addTarget with the option of withEvent, which gave me the access to the touches.
Now, after I added the target like this:
[C addTarget:self action:#selector(outsideOfKey: forEvent:) forControlEvents:UIControlEventTouchDragOutside|UIControlEventTouchDragInside];
[C addTarget:self action:#selector(keyGetsLeft: forEvent:) forControlEvents:UIControlEventTouchUpOutside | UIControlEventTouchUpInside];
(also for all of the other keys),
I maneged to make them slideable,
outsideOfKey:forEvent: is as follows:
-(void) outsideOfKey:(id)sender forEvent:(UIEvent *)event
{
for(UITouch *t in [event allTouches])
{
CGPoint touchPoint = [t locationInView:window];
if(CGRectContainsPoint(C.frame, touchPoint))
{
C.highlighted = YES;
}
else{
C.highlighted = NO;
}
(Done for all the other keys as well)
I can slide from and into other keys, and when I leave them in keyGetsLeft:forEvent: I have just used the same syntx without the else, and the highlighted became NO.
Up to here it's easy,
But then when I try to do multi-touch, I can slide only one of the touches all around and the others must stay in the same position.
And even more, If I take one of the fingers away all of them are becoming non-highlighted,
I know the reasons to all of that, but I don't know how to fix it and make it to work.

I would probably move away from UIButtons altogether and implement my own custom touch tracking code. See Handling Multitouch Events in the docs. Namely, you will be implementing the following methods:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
I would probably just implement hit areas, which you could setup in IB, with perhaps a custom UIView touch overlay (just a UIView with a custom subclass). This would let you setup the view in IB with images, titles, etc., but do all of your touch tracking in your custom subclass.

I am afraid, bensnider is right. But I'd implement it via GestureRecognizer:
https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures
https://developer.apple.com/documentation/uikit/uigesturerecognizer
Each key has one TapRecognizer, while a parent view has a SwipeRecognizer to detect slides form one key to another.
Very useful, on Apple Developer Video Archivelogin with development account required:
WWDC2010: Session 120 — Simplifying Touch Event Handling with Gesture Recognizers
WWDC2010: Session 121 — Advanced Gesture Recognition

I'd use one view for all buttons and manually implement touch tracking as bensnider said. Manually drawing backgrounds/titles also is not so difficult.

Heres a link to an open source iOS piano app I made https://github.com/meech-ward/iOSPiano
I used CALayers for the piano keys and I used
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
to detect if the user is currently touching a piano key.
It works really well even with multiple touches.

Related

Xcode: TextView scrolls quickly to top or bottom only

I'm sorry if the question is too trivial but I am completely new to xcode.
I have a textview added to my view that has quite a lot of text within. When I run the project, I can't to scroll it properly - textview is shiften as long as I hold it by mouse/finger and go back to top when I release my mouse/finger. When I try to scroll it by much with a quick move - it goes quickly to the very bottom of the textview. It looks like top and bottom act as strong magnets.
How can I make it working that when I scroll the textview slightly, it stops there? I checked some properties like bounces and other but I didn't make it working as I wanted. I'm not sure if it is important info but I defined the textview as outlet, assigned #property and synthetized it.
I tried to browse the forum but couln't find the answer for it. Thanks for any help.
In thouchesBegan method I have:
- (void)touchesBegan:(NSSet *)touches WithEvent:(UIEvent *)event{
if (text1.editing) {
[text1 resignFirstResponder];
}
[super touchesBegan:touches WithEvent:event];
}
Try to set:
yourTextView.pagingEnabled = TRUE;
or in your xib check the Paging Enabled property.
Here You need To check whether You written some code Which Move The UITextView On Moving The Finger,I Guess So. You need To check Your TouchEvents Methods ...,if So then You need to Fix that Code
These Are the TouchEvents Methods,DO check in these Methods.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
Ok if you have nothing written inside these methods related to UITextView,I would say you should take a view of properties of that UITextView as below Image depicts.
Please Have A Look At this AGain.
EDIT:Please Make SUre You have Created The UITextView With Sufficient Size.
I hope It WOuld Help You dude..!!!!!

how to create custom touch event and action

Hi i am new iphone i want to developing a application that is work on touch event. in this when user touch on screen then show a label msg u touch on right and same.
how to do this i im confused plz tell me.
Basically What you will want to look at is subclassing UIView objects (which themselvs inherit from UIResponder), inside your subclass you can implement the following methods and add the required behavior to them:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
-(void)touchesCanceled:(NSSet *)touches withEvent:(UIEvent *)event;
For more information I would look at the UIResponder.h file and the related documentation in xCode.
Another great place to continue your research and read some sample code is the Event Handling section in the iPhone Application Programming Guide

iPhone Dev: Making a tableHeaderView respond to touches

Ok, I'm a objective c noob. I have a table view with a tableHeaderView and I want it to respond to touches?
Here are some steps that I do when creating the view:
1. create a view
2. add a bunch of labels and imageviews to it
3. set my tableHeaderView to the view I created
Any help will be appreciated!
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(tapTableHeader:)];
[self.tableView.tableHeaderView addGestureRecognizer:recognizer];
- (void)tapTableHeader:(UITapGestureRecognizer *)recognizer {
NSLog(#"table header taped");
}
Is the desired touch behavior especially complex? If not, just make the part of the header that needs to respond to touches a button, slider, switch or other control.
The header view can respond to touches the same way any other view can. You can put buttons on it or you can override the UIResponder methods that handle touch events, specifically:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
add a bunch of labels and imageviews to it
Might want to be careful about that from a user interface design perspective. The effective touch area of a table header is rather small. You don't want it to have more than one or at most two components or possible actions. Otherwise, your users will need a stylus to do anything.
If you just need an image/text and to respond to taps, consider using a UIButton. It will provide you with all that functionality without subclassing.

Rotate UIImage like SPin the Bottle

I dont know if anyone of you guys know the Spin the Bottle application for the iphone. I want to make a simple app which offers the user a simple image with a bottle. The user should be able to rotate the bottle by using finger gestures. He/She should be able to rotate it with a rotation with the fingers and after releasing (touchesEnd) the bottle should spin further and slow down until it stop at a position based on the speed.
any clues or hints for a solution?
While it's better if you understand everything yourself, if you want a more concrete example the code here works
Narut's post which is like the 5th response has nice clean code for what you want.
In order to respond to a custom multi-touch gesture such as a rotation, you'll need to subclass either the image view or the view containing it and build a custom implementation of the following methods:
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
Essentially, think of the iPhone screen as a graph, and fingers as points. You use the above methods in a view to figure out how/where fingers are on the graph.
Good starting points:
http://developer.apple.com/IPhone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/EventHandling/EventHandling.html
https://stackoverflow.com/questions/tagged/multi-touch+iphone

How can I tell if a button is being pressed in my iPhone app?

How can you tell when a button is being pressed? Specifically, how can you do something while a button is down?
While the screen is touched, there will be touch events. There are also touch up and touch down events.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesBegan");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesMoved");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesEnded");
}
Then just register your controller as the touchController.
Also check out Apple's GLPaint example:
https://developer.apple.com/iphone/library/samplecode/GLPaint/
You can also do it by creating an IBAction and connecting it IB. Interface builder for iPhone can actually demux different types of events. If you ctrl-click a UIButton in your UI, and release the mouse button instead of dragging a connection you will see an inspector that shows a bunch of different actions you can wire up. When you just drag it defaults to wiring up "Touch Up Inside", but if you want you can wire up "Touch Down" or "Touch Down Repeat" and that action will be cause the appropriate selector to be called.
If you are doing complicated stuff with your own gestures then using the touchController based stuff will definitely be a better approach, but for simple things just using the built in nib based actions may be simpler.