I have created a image map which contains imageview inside scrollview , in my imageview if touch on particular portion then i want to draw text on that particular portion.
Is there any library for that ?
You can do this yourself by first getting the point of the touch, like so:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
CGPoint point = [aTouch locationInView:self];
CGFloat xPos = point.x;
CGFloat yPos = point.y;
}
And then use this information and make a method that takes x and y as in parameter. And creates a UITextField programmatically.
UITextField * textFieldRounded = [[UITextField alloc] initWithFrame:CGRectMake(inParameterX, inParameterY, 300, 50)];
textFieldRounded.textColor = [UIColor blackColor];
textFieldRounded.font = [UIFont systemFontOfSize:17.0];
textFieldRounded.backgroundColor = [UIColor clearColor];
textFieldRounded.autocorrectionType = UITextAutocorrectionTypeNo;
textFieldRounded.keyboardType = UIKeyboardTypeDefault;
textFieldRounded.returnKeyType = UIReturnKeyDone;
textFieldRounded.clearButtonMode = UITextFieldViewModeWhileEditing;
And then add it to your view:
[self.view addSubview:textFieldRounded];
Depending on what you want to do with the text field, you could make an object instead. And save the to an array perhaps. Well you get the point.
Related
I currently use the following to create a button with text using SpriteKit:
SKLabelNode *startButtonText = [SKLabelNode labelNodeWithFontNamed:#"Verdana-Bold"];
startButtonText.text = #"Start";
startButtonText.fontColor = [SKColor colorWithRed:1 green:1 blue:1 alpha:1];
startButtonText.fontSize = 24;
startButtonText.position = CGPointMake(self.size.width/2, self.size.height/2-10);
startButtonText.name=#"startButton";
SKShapeNode *startButton = [[SKShapeNode alloc] init];
startButton.path = [UIBezierPath bezierPathWithRect:CGRectMake(center.x-65.0 , center.y-20.0, 130.0, 40.0)].CGPath;
startButton.fillColor = [SKColor colorWithRed:0.188 green:0.196 blue:0.161 alpha:1];
startButton.strokeColor = nill;
startButtonText.name=#"startButton";
[startButton addChild:startButtonText];
[self addChild:startButton];
My goal is to make it so that when the screen is touched, the touch only registers startButton not start startButtonText via:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
NSLog(#"%#",node.name);
}
In action script, you would simply use:
mouseChildren = false;
Is there anyway this is possible?
Give both buttons a different name. It looks like there's a copy & paste error in your code.
Then check in your touchesBegan which button has been pressed and react on both the same way:
if ([node.name isEqualToString:#"startButton"]||[node.name isEqualToString:#"startButtonText"]) {
...
}
I'm now trying to create an application with a '3D cube', and clickable sides.
To create a '3D cube', i found a great article : here
It uses some 'layers'.
What i want to do, is done a cube in 3D, but with clickable sides. I found some examples like this :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if ([touches count] == 1) {
for (UITouch *touch in touches) {
CGPoint point = [touch locationInView:[touch view]];
point = [[touch view] convertPoint:point toView:nil];
CALayer *layer = [(CALayer *)self.view.layer.presentationLayer hitTest:point];
layer = layer.modelLayer;
layer.opacity = 0.5;
}
}
}
But this sort of code makes no difference between the different sides. So I try to make some changes to the code from the article. For example, to create the first side, the code was :
CALayer *sideOne = [CALayer layer];
sideOne.borderColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;
sideOne.backgroundColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:0.4].CGColor;
sideOne.borderWidth = Border_Width;
sideOne.cornerRadius = Corner_Radius;
sideOne.frame = layerRect;
sideOne.position = self.center;
and :
transformLayer = [CATransformLayer layer];
[transformLayer addSublayer:test.layer];
transformLayer.anchorPointZ = Layer_Size/-2;
[rootLayer addSublayer:transformLayer];
So I try to make some modifications and finally add a 'UIButton' on this side. Like this :
UIButton * test = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[test setFrame:CGRectMake(0.0, 0.0, layerSize, layerSize)];
[test addTarget:self action:#selector(ActionTest) forControlEvents:UIControlEventTouchUpInside];
test.layer.borderColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;
test.layer.backgroundColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:0.4].CGColor;
test.layer.borderWidth = Border_Width;
test.layer.cornerRadius = Corner_Radius;
test.layer.frame = layerRect;
test.layer.position = self.center;
But the problem is, when i want to add it to the side.
When i do :
transformLayer = [CATransformLayer layer];
[self addSubview:test];
[transformLayer addSublayer:test.layer];
transformLayer.anchorPointZ = Layer_Size/-2;
[rootLayer addSublayer:transformLayer];
the button no react
And when i do :
transformLayer = [CATransformLayer layer];
[transformLayer addSublayer:test.layer];
transformLayer.anchorPointZ = Layer_Size/-2;
[self addSubview:test];
[rootLayer addSublayer:transformLayer];
the button react but don't move with the rest of the cube
I understand the problem but don't know how to fix it...
Thanks !
What you're seeing is the difference between a UIButton, which inherits from UIResponder, and CALayer's, which do not make up a part of the responder chain directly.
Fortunately, there is a simple way to grab events from the responder chain and direct them towards your CALayer of choice, and it looks a little like this:
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint p = [(UITouch*)[touches anyObject] locationInView:self.worldView];
for (CALayer *layer in self.worldView.layer.sublayers) {
if ([layer containsPoint:[self.worldView.layer convertPoint:p toLayer:layer]]) {
// do something
}
}
}
It's the containsPoint:convertPoint:toLayer: that's going to hold the essence of what you seek.
There's a bit more largely relevant discussion around this topic on this post too
To connect the dots of this to your invocation, when you add the button's layer to your other layers, all the visual aspects perform as expected, but no one is a member of the responder chain, and therefore no one receives touches to handle.
i have gone through the many tutorials to drag an image on screen using touchesmoved method
but most of them are not for dynamically created imageviews
in my project i created 5 UIImageview programatically,
now i want that user can drag them on screen>> i also follow this answer
Question but all in vain , no success so far>
the code for creating the dynamically imageview is
for (int i = 0; i < index ; i++)
{
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:
[UIImageimageNamed:image_name]];
self.imageView1.userInteractionEnabled = YES;
imageView1.frame = CGRectMake(xvalue, yvalue, 80.0f, 80.0f);
self.view.userInteractionEnabled = YES;
[self.view addSubview:imageView1];
}
Thanks in advance for good replies
I'm a little confused with how you are creating UIImageViews because you are using a for-loop but a static name. So you might have 15 UIImageViews with the name "imageView1".
But anyways, this shouldn't matter at all if you are using the code in the question you linked to. Perhaps you put the lines in out of order... this is the proper order. (If it doesn't work let me know, along with the errors you get)
//-(void)ViewDidLoad? {???? is this your function??
int xvalue = 0;//?? not sure where you declared these
int yvalue = 0;//?? not sure where you declared these
for (int i = 0; i < index ; i++) {
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:
[UIImageimageNamed:image_name]];
self.imageView1.userInteractionEnabled = YES;
imageView1.frame = CGRectMake(xvalue, yvalue, 80.0f, 80.0f);
self.view.userInteractionEnabled = YES;
[self.view addSubview:imageView1];
}
self.elements=[myElements getElements];
imagesElements = [[NSMutableArray alloc]init];
for(ElemetsList *item in self.elements) {
UIImageView *oneelement = [[UIImageView alloc] initWithImage:[UIImage imageNamed:item.imgElement]];
oneelement.frame = CGRectMake(item.positionX, item.positionY, item.width, item.height);
oneelement.userInteractionEnabled=YES;
[imagesElements addObject:oneelement];
}
for(UIImageView *img in imagesElements) {
[self.view addSubview:img];
}
//}? End Function, whatever it may be...?
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
for(UIImageView *img in imagesElements)
{
if([self view] == img)
{
CGPoint location = [touch locationInView:self.view];
img.center=location;
}
}
}
If you just want to hard-code in the moving for one image try this:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
imageView1.center=[touch locationInView:self.view];
}
There are plenty of ways to address this issue. You can add UIPanGestureRecognizer to each UIImageView at the time its creation, or you can use touchesBegan:, touchesMoved: on self (assuming it's a UIViewController) and traverse each UIImageView to see if its frame contains the point of the touch.
I'd like to enable the user to resize an UITextView. I display a button in the bottom rigth corner of the UITextView such as when the user moves it, the UITextView follow it and is resized.
This is works fine but the text space has a strange behaviour. The text space seems to get smaller and smaller during the resize. So if I resize a lot, go to a big frame and then to a small frame, the text space has become smaller than the frame.
- (id) init{//My subclass of UITextView
self = [super init];
if(self){
//Resize button
//Init ResizeButton
self.resizeButton = [[UIButton alloc]init];
//Image
[self.resizeButton setImageForAllState:[UIImage imageNamed:#"Isosceles-right-triangle.png"]];
//Target
[self.resizeButton addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[self.resizeButton addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
//Add to view
[self addSubview:resizeButton];
//Self
//text font
[self setFont:[UIFont fontWithName:#"papyrus" size:17]];
}
return self;
}
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// NSLog(#"wasDragged");// get the touch
UITouch *touch = [[event touchesForView:button] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
button.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width+ delta_x, self.frame.size.height+ delta_y);
}
The view is also draggable
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// Calculate offset
CGPoint pt = [[touches anyObject] locationInView:self];
float dx = pt.x - startLocation.x;
float dy = pt.y - startLocation.y;
CGPoint newcenter = CGPointMake(self.center.x + dx, self.center.y + dy);
// Set new location
self.center = newcenter;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Calculate and store offset, and pop view into front if needed
CGPoint pt = [[touches anyObject] locationInView:self];
startLocation = pt;
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
EDIT
Before resizing
Resizing
Back to original size
Well, I have this problem too. The soliution is to subclass UITextView and override setFrame: method. Before setting your wanted frame, set CGRectZero frame for textView. It will fix your problem. Code bellow.
- (void)setFrame:(CGRect)frame
{
[super setFrame:CGRectZero];
[super setFrame:frame];
}
Seems like you could do one of two things:
First: turn off the 'Adjust to fit' of the control
textfield.adjustsFontSizeToFitWidth = NO;
Second: Hardcode a font size into the code
textfield.font = [UIFont fontWithName:#"desired font name" size:10];
I want to draw a vertical line on the place where the screen was tapped. Because the average finger is wider than 1 pixel wide I want to do this "in steps". So basically, the line can only be drawn every 25px. And I want to figure out the nearest location where I could draw a line.
For example if the finger tapps 30 pixels from the left side of my upper view, I want to draw a vertical line 25 pixels from the left side of the view. If the screen is tapped 40 pixels from the left, i want the line drawn 50 pixels from the left side. (So there can only be one line every 25 pixels and and I want to draw the nearest one.
Any idea how I could do this?
Drawing the line is easy:
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(100.0, 0.0, 1, 320.0)];
lineView.backgroundColor = [UIColor whiteColor];
[parentView addSubview:lineView];
But I have no idea how to find where the user tapped the screen.
To choose the nearest vertical line aligned to 25-point boundaries use this to calculate the correct x-value:
CGFloat spacing = 25.0f;
NSInteger lineNumber = (NSInteger)((touchPoint.x + (spacing / 2.0f)) / spacing);
CGFloat snapX = spacing * lineNumber;
Here's what happens in the code above:
Add half of the spacing value onto the touch point - this is because the 'snap' process in the next step will always find the previous line, so by adding half of the spacing value we ensure it will 'snap' to the nearest line.
Calculate the line number by dividing by the spacing and casting the value into an integer. This truncates the fractional part of the result so we now have the integer line number (0, 1, 2, 3, etc.).
Multiply by the original spacing to get the actual x-value of the line you want to draw (0, 25, 50, 75, etc.).
Create a transparent custom UIView that covers the whole screen (except the status bar) and override its (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event.
You can get the touch point with:
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
You can use ssteinberg code:
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
or adding a UITapGestureRecognizer to your view, which it is probably easier:
UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[yourParentView addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
...
- (IBAction)handleTap:(UITapGestureRecognizer *)recognizer {
CGPoint touchPoint = [recognizer locationInView:self.view];
...
And in addition, draw your line at every 25px by adding something like this:
CGFloat padding = 25.0;
NSInteger xPosition = round(touchPoint.x / padding) * padding;
[self drawLineAt:xPosition];
Refer This if you find it suitable :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (lineView) {
[lineView removeFromSuperview];
NSSet *allTouchesSet = [event allTouches];
NSArray *allTouches = [NSArray arrayWithArray:[allTouchesSet allObjects]];
int count = [allTouches count];
if (count == 1) {
UITouch *touch = [[event allTouches] anyObject];
tapPoint = [touch locationInView:self];
NSLog(#"tapPoint: %#",NSStringFromCGPoint(tapPoint));
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(tapPoint.x, 0.0, 1, 320.0)];
lineView.backgroundColor = [UIColor whiteColor];
[parentView addSubview:lineView];
}
}
}