I want to select and then highlight the same text on the label with a particular color.Is this be achievable with the help of gestures.
And i have to store the position of the highlighted part,even if the application terminas,so when the user comes back ,they can see that part highlighted
Thanks
Yes, you could use the gesture with your UILabel for highlighting text by either changing the background color or text color of your UILabel.
You could also store the current state of your UILabel using NSUserDefaults , and read it back we user launch your application.
Declare an isLabelHighlighted as BOOL for UILabel state.
UITapGestureRecognizer* myLabelGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(LabelClicked:)];
[myLabelView setUserInteractionEnabled:YES];
[myLabelView addGestureRecognizer:myLabelGesture];
-(void)LabelClicked:(UIGestureRecognizer*) gestureRecognizer
{
if(isLabelHighlighted)
{
myLabelView.highlightedTextColor = [UIColor greenColor];
}
else
{
myLabelView.highlightedTextColor = [UIColor redColor];
}
}
To store state of your UILabel.
[[NSUserDefaults standardUserDefaults] setBool:isLabelHighlighted forKey:#"yourKey"];
To access it, you should use below.
isLabelHighlighted = [[NSUserDefaults standardUserDefaults] boolForKey:#"yourKey"];
NSUserDefaults is not suitable, because the application can be terminated unexpectedly
UITapGestureRecognizer not supported any states, except UIGestureRecognizerStateEnded
- (void)viewDidLoad
{
[super viewDidLoad];
UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGestureRecognizerAction:)];
longPressGestureRecognizer.minimumPressDuration = 0.01;
[label setUserInteractionEnabled:YES];
[label addGestureRecognizer:longPressGestureRecognizer];
}
- (void)longPressGestureRecognizerAction:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
{
label.alpha = 0.3;
}
else
{
label.alpha = 1.0;
CGPoint point = [gestureRecognizer locationInView:label];
BOOL containsPoint = CGRectContainsPoint(label.bounds, point);
if (containsPoint)
{
// Action (Touch Up Inside)
}
}
}
Related
I have a tutorial for my app, which should display only the first time the app is opened and should be tapped to dismiss.
I am initializing a UITapGestureRecognizer in my viewDidLoad:
tapper_tut = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
tapper_tut.cancelsTouchesInView = FALSE;
[self.view addGestureRecognizer:tapper_tut];
and I have an IBAction to detect the tap and set the tutorial to hidden:
- (IBAction)dismiss_tut{
if (????????????????) {
_tutorial.hidden = YES;
}
}
But I have no idea what to put in the if statement condition, or if this is even that right way to go about this.
How would I dismiss a UIImageView on a tap?
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[self.view addGestureRecognizer:gr];
// if not using ARC, you should [gr release];
// mySensitiveRect coords are in the coordinate system of self.view
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
CGPoint p = [gestureRecognizer locationInView:self.view];
if (CGRectContainsPoint(mySensitiveRect, p)) {
NSLog(#"got a tap in the region i care about");
} else {
NSLog(#"got a tap, but not where i need it");
}
}
You can make viewDidLoad like this
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
/* Create the Tap Gesture Recognizer */
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTaps:)];
/* The number of fingers that must be on the screen */
self.tapGestureRecognizer.numberOfTouchesRequired = 1;
/* The total number of taps to be performed before the gesture is recognized */
self.tapGestureRecognizer.numberOfTapsRequired = 1;
/* Add this gesture recognizer to the view */
[self.view addGestureRecognizer:self.tapGestureRecognizer];
}
To detect the taps you can make the method like this.
- (void) handleTaps:(UITapGestureRecognizer*)paramSender
{
NSUInteger touchCounter = 0;
for (touchCounter = 0;touchCounter < paramSender.numberOfTouchesRequired;touchCounter++)
{
CGPoint touchPoint =[paramSender locationOfTouch:touchCounter inView:paramSender.view];
NSLog(#"Touch #%lu: %#",(unsigned long)touchCounter+1, NSStringFromCGPoint(touchPoint));
}
}
you have to declare .h file as "UIGestureRecognizerDelegate"
you have getting tap of gesture as two way as given below steps.
1) Call delegate method of GestureRecognizer (not given action )
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil]; // not given action.
recognizer.numberOfTouchesRequired=1;// here how many tap you want set it
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//whatever you want write code here
return NO;
}
2) given action
UITapGestureRecognizer *oneTouch=[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(Addphoto)];
[oneTouch setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:oneTouch];
-(IBAction)Addphoto
{
//whatever you want write code here
}
may be it will help .
I think u need to detect the first time launch of the application which u can do with following
![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"]
Put this in your if statement .
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
How can I detect when the user taps the selection indicator in a UIDatePicker?
Without this the user has to scroll to some other date and then back again to pick the date which is displayed under the selection indicator when the date picker slides up.
Thanks a lot,
Stine
UPDATE: This is the only solution I could come up with myself:
UIDatePicker *aDatePicker = [[UIDatePicker alloc] init];
self.datePicker = aDatePicker;
[aDatePicker release];
[self.datePicker addTarget:self action:#selector(datePicked:) forControlEvents:UIControlEventValueChanged];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(datePicked:)];
[self.datePicker addGestureRecognizer:tap];
[tap release];
Which means that datePicked will be called twice when the user actually rotates the wheel.
UPDATE: The above mentioned solution does not work for UIPickerViews though. I do not know how to achieve the wanted behavior in those cases.
You can do some tweak in this way:-
Conform delegate <UIGestureRecognizerDelegate>in your .h file
UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pickerViewTapGestureRecognized:)];
[yourDatePicker addGestureRecognizer:gestureRecognizer];
gestureRecognizer.delegate=self;
gestureRecognizer.numberOfTapsRequired=2;//Whenever you do double tap it will called. So allow user to do double tap on selected date.
//Below is the Delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
//Below method will trigger when do the double tap
-(void)pickerViewTapGestureRecognized:(UITapGestureRecognizer*)recognizer
{
UIDatePicker *datePicker=(UIDatePicker*)[[recognizer view] viewWithTag:101];
NSLog(#"datePicker=%#", datePicker.date);
}
Try this code:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pickerViewTapped:)];
[recognizer setNumberOfTapsRequired:2];
[recognizer setCancelsTouchesInView:NO];
[recognizer setDelaysTouchesEnded:NO];
[recognizer setDelaysTouchesBegan:NO];
[self.answerPicker addGestureRecognizer:recognizer];
// ....
- (IBAction)pickerViewTapped:(UITapGestureRecognizer *)sender {
CGPoint coord = [sender locationInView:self.answerPicker];
if(coord.y <= 126 && coord.y >= 90) {
//do something
}
}
This is an old question but here's what I did in order to grab the selection bar rect on the UIDatePicker. With this, you could just add a button/view with a gesture recognizer to detect taps. It's a bit of a hack but it seems to be working well in iOS6 and iOS7.
+ (CGRect)getSelectionBarRectFromPicker:(UIDatePicker *)picker
{
int counter = 0;
CGRect selectionBarRect;
for(UIView *datePickerView in picker.subviews){
for(UIView *subview in datePickerView.subviews){
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0){
if([NSStringFromClass([subview class]) isEqualToString:#"_UIPickerViewSelectionBar"]){
if(counter == 0){
selectionBarRect.origin = subview.frame.origin;
selectionBarRect.size.height = subview.frame.size.height;
}
selectionBarRect.size.width += subview.frame.size.width;
counter++;
}
} else {
if(subview.frame.size.height < 1){
if(counter == 0){
selectionBarRect.origin = subview.frame.origin;
selectionBarRect.size.width = subview.frame.size.width;
} else {
selectionBarRect.size.height = subview.frame.origin.y - selectionBarRect.origin.y;
}
counter++;
}
}
}
}
return selectionBarRect;
}
Hola guys.
I'm experiencing a little problem with touch handling and UIResponder.
My goal is to manage a single touch (moved) to interact with different views.
I added a gesture recognizer to my UIImageView that send a simple message to my customViewController. It allocate and display a custom view (subclassing a UIButton) over the tapped UIImageView.
I would be able (without have to release the initial finger tap) to send touch movement to my new allocated custom button.
It seems that my UIImageView swallow my touch and so my new Button can't feel the finger movement.
I tried to resign first responder but it seems having no effect.
My custom Button work pretty good but only if I release the first tap and then tap again over the new displayer button.
Any suggests?
Thank you in advance.
Some code here:
Inside my viewController I attached a longPressGestureRecognizer to my profileImageView that draw a circular button surrounding the profileImageView.
-(void)showMenu:(UIGestureRecognizer*)gesture {
[profileImageView removeGestureRecognizer:gesture];
[profileImageView setUserInteractionEnabled:NO];
ConcentricRadius radius;
radius.externalRadius = 75;
radius.internalRadius = 45;
GTCircularButton *circularMenu = [[[GTCircularButton alloc] initWithImage:[UIImage imageNamed:#"radio.png"] highlightedImage:[UIImage imageNamed:#"radio_selected.png"] radius:radius] autorelease];
[circularMenu setTag:kCircularTagControllerCircularMenu];
[circularMenu setCenter:[profileImageView center]];
// Buttons' frames will be set up by the circularMenu
UIButton *button1 = [[[UIButton alloc] init] autorelease];
UIButton *button2 = [[[UIButton alloc] init] autorelease];
UIButton *button3 = [[[UIButton alloc] init] autorelease];
UIButton *button4 = [[[UIButton alloc] init] autorelease];
[circularMenu setButtons:[NSArray arrayWithObjects:button1, button2, button3, button4, nil]];
//[[self view] addSubview:circularMenu];
[[self view] insertSubview:circularMenu belowSubview:profileImageView];
}
Now I handle manually the touchEvent inside the circularMenu using the touchMoved methods.
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchLocation = [(UITouch*)[touches anyObject] locationInView:self];
for (UIView *aSubview in _roundButtons) {
if ([aSubview isKindOfClass:[UIButton class]]) {
UIButton *aButton = (UIButton*)aSubview;
CGPoint buttonTouchPointConverted = [aButton convertPoint:touchLocation toView:aButton];
if (CGRectContainsPoint([[aButton layer] frame], buttonTouchPointConverted)) {
[self rotateHighlightImage:aButton];
}
}
}
}
The goal is always to handle the end of gestureRecognizer and pass the touch event to the new instance created without having to lift my finger from the screen.
Any ideas?
PD: I handle touch manually with touchMoved cause if I use the addTarget:action:forControlEvents: on my buttons (1,2,3, and 4) the button that detect touchEvent swallow it and make other buttons impossible to feel the touch moving over them.
Your touchesEnded:withEvent: will have to be the same as your touchesMoved:withEvent: except it must invoke the method which is probably tied to the control event Touch Up Inside event.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchLocation = [(UITouch*)[touches anyObject] locationInView:self];
for (UIView *aSubview in _roundButtons) {
if ([aSubview isKindOfClass:[UIButton class]]) {
UIButton *aButton = (UIButton*)aSubview;
CGPoint buttonTouchPointConverted = [aButton convertPoint:touchLocation toView:aButton];
if (CGRectContainsPoint([[aButton layer] frame], buttonTouchPointConverted)) {
[aButton sendActionsForControlEvents:UIControlEventTouchUpInside];
return;
}
}
}
}
The only change I have made is to have the button send that control event for us.
Original Answer
In the function that handles your gesture, do this,
if ( gesture.state == UIGestureRecognizerStateEnded ) {
CGPoint point = [gesture locationInView:button];
if ( CGRectContainsPoint(button.bounds, point) ) {
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
This checks whether the last touch of the gesture was inside the button and sends a touch up inside event to all its targets.
Ok guys finally I solved my problem and I reached my goal!!
I discovered what was the real problem.
Simply the GestureRecognizer handle touch Event until it's state is setted to UIGestureRecognizerStateEnded and for this reason the GestureRecognizer swallow touch events with no opportunity to send touch events to the rest of responder chain.
I read again the UIGestureRecognizer class reference and I found the property enabled.
To solve my problem the first thing I do when the gesture launch the target method is to set the gesture enabled to NO. In this way the gesture release immediately the touch control and the touchMoved can be executed.
Hope this help someone.
Above the modified code:
-(void)showMenu:(UIGestureRecognizer*)gesture {
[gesture setEnabled:NO]; // This is the key line of my problem!!
[profileImageView removeGestureRecognizer:gesture];
[profileImageView setUserInteractionEnabled:NO];
ConcentricRadius radius;
radius.externalRadius = 75;
radius.internalRadius = 45;
GTCircularButton *circularMenu = [[[GTCircularButton alloc] initWithImage:[UIImage imageNamed:#"radio.png"] highlightedImage:[UIImage imageNamed:#"radio_selected.png"] radius:radius] autorelease];
[circularMenu setTag:kCircularTagControllerCircularMenu];
[circularMenu setCenter:[profileImageView center]];
// Buttons' frames will be set up by the circularMenu
UIButton *button1 = [[[UIButton alloc] init] autorelease];
UIButton *button2 = [[[UIButton alloc] init] autorelease];
UIButton *button3 = [[[UIButton alloc] init] autorelease];
UIButton *button4 = [[[UIButton alloc] init] autorelease];
[circularMenu setButtons:[NSArray arrayWithObjects:button1, button2, button3, button4, nil]];
//[[self view] addSubview:circularMenu];
[[self view] insertSubview:circularMenu belowSubview:profileImageView];
}
I think you should change a setting on the view, once you create the button. Eg.
myImageView.userInteractionEnabled = NO;
This way, the UIImageView will not listen to the touches any more.
Let me know if it works.
when I press on it I can change position freely in View
-(IBAction) add :(id)sender {
CGRect frame = CGRectMake(kLeftMargin, 8.0, kTextFieldWidth, kTextFieldHeight);
UITextField * textfieldToAdd = [[[UITextField alloc] initWithFrame:frame] autorelease];
textfieldToAdd.borderStyle = UITextBorderStyleRoundedRect;
textfieldToAdd.textColor = [UIColor blackColor];
textfieldToAdd.font = [UIFont systemFontOfSize:17.0];
textfieldToAdd.placeholder = #"";
textfieldToAdd.backgroundColor = [UIColor whiteColor];
textfieldToAdd.autocorrectionType = UITextAutocorrectionTypeNo ; // no auto correction support
textfieldToAdd.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard)
textfieldToAdd.returnKeyType = UIReturnKeyDone;
textfieldToAdd.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
textfieldToAdd.tag = kViewTag; // tag this control so we can remove it later for recycled cells
textfieldToAdd.delegate = self; // let us be the delegate so we know when the keyboard's "Done" button is pressed
// Add an accessibility label that describes what the text field is for.
[textfieldToAdd setAccessibilityLabel:NSLocalizedString(#"textfieldToAdd", #"")];
[self.view addSubview:textfieldToAdd];
}
First add the gestureRecognizer to your ViewDidLoad and then create the function
or better look here MoveME example
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panPiece:)];
[panGesture setMaximumNumberOfTouches:2];
[panGesture setDelegate:self];
[self addGestureRecognizer:panGesture];
- (void)panPiece:(UIPanGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGPoint translation = [gestureRecognizer translationInView:self.view];
textfieldToAdd.center = CGPointMake([self center].x + translation.x, [self center].y + translation.y);
[gestureRecognizer setTranslation:CGPointZero inView:[self superview]];
}
}
i want dragging this textField
(void)viewDidLoad {
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(add:)] autorelease];
}
-(IBAction) add :(id)sender {
CGRect frame = CGRectMake(kLeftMargin, 8.0, kTextFieldWidth, kTextFieldHeight);
UITextField * textfieldToAdd = [[[UITextField alloc] initWithFrame:frame] autorelease];
textfieldToAdd.borderStyle = UITextBorderStyleRoundedRect;
textfieldToAdd.textColor = [UIColor blackColor];
textfieldToAdd.font = [UIFont systemFontOfSize:17.0];
textfieldToAdd.placeholder = #"";
textfieldToAdd.backgroundColor = [UIColor whiteColor];
textfieldToAdd.autocorrectionType = UITextAutocorrectionTypeNo ; // no auto correction support
textfieldToAdd.keyboardType = UIKeyboardTypeDefault; // use the default type input method (entire keyboard)
textfieldToAdd.returnKeyType = UIReturnKeyDone;
textfieldToAdd.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
textfieldToAdd.tag = kViewTag; // tag this control so we can remove it later for recycled cells
textfieldToAdd.delegate = self; // let us be the delegate so we know when the keyboard's "Done" button is pressed
// Add an accessibility label that describes what the text field is for.
[textfieldToAdd setAccessibilityLabel:NSLocalizedString(#"textfieldToAdd", #"")];
[self.view addSubview:textfieldToAdd];
}