Move image like facebook chat - ios

I want to make animation like facebook chat: chat heads. I created a icon. It worked fine and quite smooth. I created more icons. They worked, too. But not consistent like facebook. Is there any idea or reference to implement the features move?
Like this video:
Chat heads

Try this May be help full .. But It's have done for UIButton..
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Drag me!" forState:UIControlStateNormal];
// add drag listener
[button addTarget:self action:#selector(wasDragged:withEvent:)
forControlEvents:UIControlEventTouchDragInside];
// center and size
button.frame = CGRectMake((self.view.bounds.size.width - 100)/2.0,
(self.view.bounds.size.height - 50)/2.0,
100, 50);
// add it, centered
[self.view addSubview:button];
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// 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);
}
I got this from here ..for more info you can find here .. Draggable UIButton makes in iPhone & iPad

Related

How to move UIView by longPress on button and then dragging?

I want to move some UIView by button inside this view.
I can it, in that way:
- (void)viewDidLoad
{
[button addTarget:self action:#selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
[button addTarget:self action:#selector(dragMoving:withEvent:) forControlEvents: UIControlEventTouchDragInside];
[button addTarget:self action:#selector(dragEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
}
.
- (void)dragBegan:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
}
- (void)dragMoving:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
//This is moving view to touchPoint
SimpleView.center = touchPoint;
}
- (void)dragEnded:(UIControl *)c withEvent:ev {
}
How can i move it only then, if I do longPress on that button?
Try using this code. I've used this in a card game i developed. moving cards around using long press gestures. Hope i helps.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(addLongpressGesture:)];
[longPress setDelegate:self];
[YOUR_VIEW addGestureRecognizer:longPress];
- (void)addLongpressGesture:(UILongPressGestureRecognizer *)sender {
UIView *view = sender.view;
CGPoint point = [sender locationInView:view.superview];
if (sender.state == UIGestureRecognizerStateBegan){
// GESTURE STATE BEGAN
}
else if (sender.state == UIGestureRecognizerStateChanged){
//GESTURE STATE CHANGED/ MOVED
CGPoint center = view.center;
center.x += point.x - _priorPoint.x;
center.y += point.y - _priorPoint.y;
view.center = center;
// This is how i drag my views
}
else if (sender.state == UIGestureRecognizerStateEnded){
//GESTURE ENDED
}
I would use this link provided by #Coder404 to detect whether or not the player used a long touch. Then, add an #property BOOL performedLongTouch and set that to YES in the selector passed into the UILongPressGestureRecognizer
Then, in your dragBegan and dragMoving functions, add a check for performedLongTouch and in your dragEnded function, set its value to NO
I know that seem pretty straight forward, but is that what you were looking for?

Draggable UIButton Snap To a Circle Path

Hi I am looking to make my UIButton be able to be draggable only around a circle I created through a draw rect. I may need to make a circle path instead of the circle shape however I'm not quite sure about the approach to take as I am new to this. Here is the code I have and I only want the button to be dragged around that circle or invisible path. Any help or examples would be extremely helpful. Thank You!
Edit: I used part of the answer below below but I am not sure how to get this to work correctly. I want it to be the same size as my circle that I created so I am happy to create just a circle path and put it on top of the circle that I made.
//Button Code
timeSetButton = [UIButton buttonWithType:UIButtonTypeCustom];
[timeSetButton addTarget:self
action:nil
forControlEvents:UIControlEventTouchDown];
[timeSetButton setImage:[UIImage imageNamed:#"testButton.png"] forState: UIControlStateNormal];
timeSetButton.frame = CGRectMake(0,415,50,50);
[self.view addSubview:timeSetButton];
//Button Listener
[timeSetButton addTarget:self action:#selector(wasDragged:withEvent:)
forControlEvents:UIControlEventTouchDragInside];
//Draggable Button Code
// get the touch
UITouch *touch = [[event touchesForView:timeSetButton] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:timeSetButton];
CGPoint location = [touch locationInView:timeSetButton];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
timeSetButton.center = CGPointMake(timeSetButton.center.x + delta_x,
timeSetButton.center.y + delta_y);
// enforce constraint on locations, by...
// working out the distance from the centre of the circle
CGPoint vectorFromCentreOfCircle =
CGPointMake(150,150);
CGFloat distanceFromCentreOfCircle = hypotf(vectorFromCentreOfCircle.x, vectorFromCentreOfCircle.y);
// working out what you'd need to multiply that distance by in order
// to get the specified radius
CGFloat correctionMultiplier = 20 / distanceFromCentreOfCircle;
// adjust vector from centre of circle
vectorFromCentreOfCircle.x *= correctionMultiplier;
vectorFromCentreOfCircle.y *= correctionMultiplier;
// move button one more time
timeSetButton.center = CGPointMake(
200 + vectorFromCentreOfCircle.x,
200 + vectorFromCentreOfCircle.y);
Here is the Circle Shape
circleView = [[CircleView alloc] initWithFrame:CGRectMake(55, 100, 260, 260)];
circleView.backgroundColor = [UIColor clearColor];
[self.view addSubview:circleView];
[self.view sendSubviewToBack:circleView];
I actually needed the same and was watching your code. What you actually need to do is fetch the angle of the actual circle and then calculate the needed x and y on that. This is how I have done it:
UIButton *button = (UIButton *) sender;
UITouch *touch = [[event touchesForView:button] anyObject];
//Drawing the circle
CGPoint arcCenter = CGPointMake(385.0f, 700.0f);
CGFloat arcRadius = 140.0f;
// 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);
CGFloat angle = atan2((button.center.y - arcCenter.y), (button.center.x - arcCenter.x));
button.center = CGPointMake(arcCenter.x + arcRadius * cos(angle), arcCenter.y + arcRadius * sin(angle));
This gives me when I add a drag to a button the actual needed behavior. I used Touch Drag Outside and Inside to avoid the button to stop when you move your finger too much away from the button. I hope it will help you too.
For this sort of thing it's probably sufficient just to add a quick bit of code after you've moved the button to enforce the constraint that it must be on the circle. E.g.
// move button
timeSetButton.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
// enforce constraint on locations, by...
// working out the distance from the centre of the circle
CGPoint vectorFromCentreOfCircle =
CGPointMake(timeSetButton.center.x - centreOfCircle.x,
timeSetButton.center.x - centreOfCircle.y);
CGFloat distanceFromCentreOfCircle =
hypotf(vectorFromCentreOfCircle.x, vectorFromCentreOfCircle.y);
// working out what you'd need to multiply that distance by in order
// to get the specified radius
CGFloat correctionMultiplier = radiusOfCircle / distanceFromCentreOfCircle;
// adjust vector from centre of circle
vectorFromCentreOfCircle.x *= correctionMultiplier;
vectorFromCentreOfCircle.y *= correctionMultiplier;
// move button one more time
timeSetButton.center = CGPointMake(
centreOfCircle.x + vectorFromCentreOfCircle.x,
centreOfCircle.y + vectorFromCentreOfCircle.y);
You can do this simply by knowing the distance of touchPoint from the center of the view
I'll make the following modification in your code. See if this works
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// get the touch
UITouch *touch = [[event touchesForView:button] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
//calculate center of button in superView
CGPoint buttonCenter = CGPointMake(button.frame.origin.x+(button.frame.size.width/2.0f),
button.frame.origin.y+(button.frame.size.height/2.0f));
//calculate the distance of current touchPoint from buttonCenter
CGFloat diffx = location.x - buttonCenter.x;
CGFloat diffy = location.y - buttonCenter.y;
CGFloat distance = sqrtf((diffx*diffx)+(diffy*diffy));
//check if the distance is within the radius of circle.
//assuming that your button is always a square to make
//perfect circle within it.
CGFloat radius = button.frame.size.width/2.0f;
if(radius >= distance)//this makes a circular check.
{
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
timeSetButton.center = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
}
}

Why a subView won't stay in the parent frame?

I have a view and inside it there's a UIImage. The image isn't static and I can move it around if I drag my finger around (using drag events) The problem is that sometimes the picture moves outside of the UIView frame. What's the appropriate way to keep it inside the parent frame bounds?
--UIViewA
--------UIViewB
--------------UIImage
--------------UIButton
I want to keep UIImage inside UIViewB
- (IBAction)myButtonSingleTap:(UIButton *)sender {
imDragging = YES;
[_myButton addTarget:self action:#selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
}
- (IBAction)myButtonDragInside:(UIButton *)sender
{
[_myButton addTarget:self action:#selector(draging:withEvent:) forControlEvents: UIControlEventTouchDragInside];
}
- (void)dragBegan:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
startingTouchPoint = [touch locationInView:self.view];
}
- (void)draging:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
currentTouchPoint = [touch locationInView:self.view];
_movingPic.frame = CGRectMake(currentTouchPoint.x, currentTouchPoint.y, 28, 23);
}
You will need to check the location of the view during the dragging.
At some point you will be setting the frame of the image depending on the user's drag direction, etc...
During this you should have a logic check like...
If new location x value is less than 0 then set new location x = 0.
If new location x value plus image width is greater than view width then set new location x = view width - image width.
etc...
Then use the new location as the point to move the image to.
Try adding the touch recogniser to the parent view and not the entire view
Before setting the new frame, make sure it is contained by the moving view's superview's bounds.
- (void)draging:(UIControl *)c withEvent:ev
{
UITouch *touch = [[ev allTouches] anyObject];
currentTouchPoint = [touch locationInView:self.view];
CGRect newFrame = CGRectMake(currentTouchPoint.x, currentTouchPoint.y, 28, 23);
newFrame.x = MAX(newFrame.x, 0);
newFrame.y = MAX(newFrame.y, 0);
newFrame.x = MIN(newFrame.x, _movingPic.superview.bounds.size.width - 28);
newFrame.y = MIN(newFrame.y, _movingPic.superview.bounds.size.height - 23);
_movingPic.frame = newFrame;
}

UITextView text space go smaller during rezise

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];

Make a swipe button

I want to make a swipe button, so when user swipe the button from right to left the button also draw towards right to left and at the end it will push the another view, can anybody give sample code for it.
// make button
UIButton*btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(50, 50, 50, 50)];
[btn addTarget:self action:#selector(wasDragged:withEvent:)
forControlEvents:UIControlEventTouchDragInside];
[self.view addSubview:btn];
// here swipe buttons
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// 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
CGPoint moveBtnCenter = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
button.center = moveBtnCenter;
NSArray* allSubViews = [self.view subviews];
for (UIView*subView in allSubViews)
{
if ([subView isKindOfClass:[UIButton class]])
{
CGPoint subViewCenter = subView.center;
if (CGPointEqualToPoint(moveBtnCenter, subViewCenter))
{
subView.center = previousLocation;
}
}
}
}

Resources