How to allow cursor move to any position in UITextView - objective-c

I have UITextView subclass with no keyboard, that use buttons for input. I want to allow move cursor by tap to any position, not only to start or end of word. That's how it's works now:
That's what I want:
I think that solution for this problem is quite complex for beginner, so I ask you for a bit more detailed description how to do it.
I have found this
but dont know where should I use this part of code.
Here is solution:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.nextResponder touchesBegan:touches withEvent:event];
UITouch *userTouch = [[event allTouches] anyObject];
CGPoint currentPos = [userTouch locationInView:self];
UITextPosition *cursorPosition=[self closestPositionToPoint:CGPointMake(currentPos.x, currentPos.y)];
[self setSelectedTextRange:[self textRangeFromPosition:cursorPosition toPosition:cursorPosition]];
}

Related

UISlider change values by touching its track

I am beginner in ios and I have done basic functionality with UISlider , changing its value on dragging thumb. But now in my app I want to move the thumb of slider gradually in same direction where I am touching slider's track without dragging the thumb of slider. Thumb must reach to exact touched position on the track in 2 or more steps.
I know it requires involvement of UITouch but unable to understand HOW?
You need to subclass UISlider to add this functionality. After subclassing, you need to implement touchesBegan and touchedMoved in your subclass. Well, here how i did
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGFloat maxX = CGRectGetMaxX(self.frame);
CGFloat minX = CGRectGetMinX(self.frame);
int value = (maxX - minX) /(self.maximumValue - self.minimumValue);
[self setValue:([touch locationInView:self].x - minX) / value animated:YES];
[self beginTrackingWithTouch:touch withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[self continueTrackingWithTouch:[touches anyObject] withEvent:event];
}
You need more work to stabilise a little bit more when user first tap, but i hope you get the idea.

Dragging multiple images in iOS

I'm brand new to touch and drag, and I'm trying to make eight draggable images. Here's what it looks like in my ViewController.m file:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
//check for which peg is touched
if ([touch view] == darkGreyPeg){darkGreyPeg.center = location;}
else if ([touch view] == brownPeg){brownPeg.center = location;}
//there are six more else ifs
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[self touchesBegan:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self ifCollided];
}
If I take out the if statements, and the locationInView:self.view to locationInView:touch.view, I'm able to drag the darkGreyPeg around with no problems, and it triggers my [ifCollided] whenever appropriate.
I'm watching a youTube tutorial (Milmers Xcode tutorials, "Dragging Multiple Images"), and he has exactly this same type of code, and mine doesn't work. Can anyone point me in the direction of why?
Thanks.
Try to check the User interaction Enabled & multiple touch in your view images atribute. Without check the user interaction enabled you can't use multiple dragging. I have try this, and succes to drag multiple image, label or button.
You should not implement these methods in your ViewController, but in your View class that you want to be able to drag around instead.
I think the problem is using == to compare objects:
[touch view] == darkGreyPeg
You should use isEqual: to compare objects:
[[touch view] isEqual:darkGrayPeg]
After Edit: I think the problem is that you forgot to set userInteractionEnabled to YES for the image views. Without doing that, the touch.view will be the superview, not the image view. Also, you probably don't need all those if statements to determine which image view to move, you can just use touch.view:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if (![touch.view isEqual:self.view]) touch.view.center = location;
}
If you have other views, besides self.view that you don't want to move, then you either have to exclude them too, or use a different exclusion condition (like only move the object if it's an image view, or only an object with a certain tag value).

Dragging UIImages to the selected area

Newbie obj-c question.
My task is to make visually represented test for iPad. In view I have three UIImages (with images of answers to test question) what will dragged to area for answer. If selected right image, then it needs to stay in this area, if not - it goes back into the start position. If user stop dragging not in area for answer it also needs to goes back to the start position.
I tried to implement this: http://www.cocoacontrols.com/platforms/ios/controls/tkdragview but it's too hard for me because I am a super newbie.
I implemented simple dragging of images by PanRecognizer, so every from three images dragging
-(IBAction)controlPan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
If I think in right way, I need to set CGPoint's with start and destination coordinates and then to customize Pan Gestures method? If it's not right, in what way can I do this?
You can consider this three method, maybe these are easier for you:
– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesEnded:withEvent:
Detailed demo for – touchesBegan:withEvent: is:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touched = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touched.view];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touched = [[event allTouches] anyObject];
// Here I suppose self.imageView contains the image user is dragging.
CGPoint location = [touch locationInView:touched.view];
// Here the check condition is the image user dragging is absolutely in the answer area.
if (CGRectContainsRect(self.answerArea.frame, self.imageView.frame)) {
// set transition to another UIViewController
} else {
self.imageView.center = location; // Here I suppose you just move the image with user's finger.
}
}
Here is the Apple's doc for this UIResponder Class Reference

Objective C: Stop Scrolling on Touch

I am trying to temporarily stop the scrolling of my view when the user starts to touch the screen and move.
I have coded this
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if (touch){
[scrollView setScrollEnabled:FALSE];
}
}
it is not working.
If you have a ScrollView and the User touches it its Defaults beheviour that it stops to scroll.
If this is not whatyou ment please be more specific what you want ;)
try this:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[scrollView setScrollEnabled:FALSE];
}
now i just wonder where you enable it again...

ccTouchesBegan vs ccTouchBegan - Touch Detection & SIGABRT crash

I'm currently doing an application where I'm trying to detect touch-positions of the user.
I changed from ccTouchBegan to ccTouchesBegan in the process of implementing the "detect touch-position" function.
But I can't get it to work. I changed from ccTouchBegan to ccTouchesBegan:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
instead of using:
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
When i did this the whole thing crashes when I click the screen. Generating a SIGABRT error higlighting:
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
NSAssert(NO, #"Layer#ccTouchBegan override me");
return YES;
}
#endif
#end
So my questions are:
Why do you think it crashes?
What's the difference between ccTouchBegan & ccTouchesBegan? Multi touch abilities?
For further help, this is my code:
-(id) init
{
if( (self=[super init])) {
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
self.isTouchEnabled = YES;
// Set up background
background = [CCSprite spriteWithFile:#"Image.png"];
background.scaleX = 1;
background.scaleY = 1;
background.position = ccp(0,0);
[self addChild:background];
[[CCTouchDispatcher sharedDispatcher]addTargetedDelegate:self
priority:0
swallowsTouches:YES];
// Preload sound effect
soundFile = [SimpleAudioEngine sharedEngine];
if (soundFile != nil) {
[soundFile preloadBackgroundMusic:#"sound.wav"];
}
}
return self;
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
NSLog(#"ccTouchesBegan");
// Sets the sound variable to YES
ifOne = YES;
prevPos = [touch locationInView:[touch self]];
prevPos = [[CCDirector sharedDirector] convertToGL:[touch locationInView:touch.self]];
[self schedule:#selector(timerUpdate:) interval:0.1];
//return YES;
}
It's a nice feature in cocos2d which lets you swallow touches in cases that you want to handle only a single touch event.
Try adding this function to your class:
- (void) registerWithTouchDispatcher {
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:INT_MIN+1 swallowsTouches:YES];
}
ccTouchesBegan happens the second you tap the screen
ccTouchesEnded happens the second you let go after tapping on the screen
and instead of
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
instead of using:
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{
try using
-(void)ccTouchesBegan:(UITouch *)...
or
-(void)ccTouchesBegan:(NSSet *)...
or
-(BOOL)ccTouchesBegan:(NSSet *)...
your problem may just be invalid data types or some crap like that, my advice is just try switching the types of touches around.
I would give more info but you didn't provide alot of information to work with, so this is the best I can do.