I have an draggable UIImageView that at some point changes to another UIImageView frame. Problem is I need to make the transformation using the same clicked point in the first UIImageView. I simply do this:
_firstImageView.frameSize = _secondImageView.frameSize;
But the frame changes from the _firstImageView origin. I need to do the transformation from the point I clicked inside the _firstImageView:
CGPoint clickedPoint = [sender locationInView:self.view];
I had tried the layer.anchorPoint but that makes the imageView disappear, don't know why (I did first a conversionPoint from self.view to the _firstImageView reference system)
EDIT e.g for better explanation of problem:
I have a uiimage1 frame with height of 100. And another with 50.
If I click in the point (y=90) of uiimage1 and start dragging, there's an test intersection that I make and if intersects it changes that UIImage1 to the frame of UIImage2. But since the click was on y=90 and UIImage2 only has max y-height of 50, it changes the frame size by the UIImage1 origin. I continue dragging with the click point outside the new frame (that is only y-height=50 and point click is y=90). My question is: Can I change the frame not by its origins but by that point clicked position?
Thanks in advance
+(CGRect)getUpdatedFrame:(CGRect)frame byChangingCenterTo:(CGPoint)newCenter
{
float width = frame.size.width;
float height = frame.size.height;
return CGRectMake(newCenter.x-width/2, newCenter.y-height/2, width, height);
}
+(CGPoint)centerForRect:(CGRect)rect
{
return CGPointMake( rect.origin.x+rect.size.width/2 , rect.origin.y+rect.size.height/2 );
}
Related
I'm trying to get a UIButton to scale but remain at its original center point, and I'm getting perplexing results with CGAffineTransformScale.
Here's the function in my UIButton subclass:
-(void)shrink {
self.transform = CGAffineTransformMakeScale(0.9,0.9);
}
With this code, the button scales to the top-left corner, but when I add code to try to set the anchor point (either of the following lines), the button gets relocated off screen somewhere:
[self.layer setAnchorPoint:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)];
//same result if I use bounds instead of frame
[self.layer setAnchorPoint:self.center];
Interestingly, this line causes the view to move down and to the right some distance:
[self.layer setAnchorPoint:CGPointMake(0, 0)];
Sorry, I know there are many posts on this topic already but I honestly read and tried at least a dozen and still couldn't get this to work. I'm probably just missing something incredibly simple.
The default anchor point is 0.5, 0.5. That is why setting it to 0, 0 moves the view down and to the right. Also, if you don't want the center to move, you need to re-adjust the center after scaling it.
Just readjust its position after shrinking it.
-(void)shrink {
CGPoint centerPoint = self.center;
self.transform = CGAffineTransformMakeScale(0.9,0.9);
self.center = centerPoint;
}
I have a UIImageView that I am able to move on my screen. However, what I would like to know is the center point of the UIImageView after the user has stopped moving it. My UIImageView is located inside my main view.
I have tried using:
CGPoint centerPoint = _imageView.center;
but unfortunately, this value remains the same regardless of where I move the UIImageView on the screen. How can I determine the center point of the UIImageView that is dynamic due to the fact that the user will be moving the UIImageView on the screen?
You can do
CGRect frame = _imageView.frame;
And then do some math with the x coord, y coord, height, and width to get the center with respect to your main view.
I have a UIImageView that I am able to move in my View by dragging it. The UIImageView is contained inside my main UIView. What I am trying to determine is the center point (CGPoint) of the UIImageView after the user has stopped dragging it. I have the following code:
CGRect frame = _imageView.frame;
CGPoint newCenterPoint = _imageView.center;
NSLog(#"The old center point for the UIImageView is: %#", NSStringFromCGPoint(newCenterPoint));
newCenterPoint.x = frame.origin.x + frame.size.width/2;
newCenterPoint.y = frame.origin.y + frame.size.height/2;
NSLog(#"The new center point for the UIImageView is: %#", NSStringFromCGPoint(newCenterPoint));
With my above code, I notice that the values for newCenterPoint are not updated. Can anyone see what it is I am doing wrong, and what I can do to find the center of the UIImageView after the user has finished moving it?
Thanks in advance to all who reply.
When you have finished moving the view, both the frame and center properties have already been updated. So you don't need to do any calculation, you just read the value.
What you code does is to print the new value of center, then calculate the center from the frame. They are, and should be, the same thing.
I am creating a UIImageView and adding it in a loop to my view, I set the initial frame to 0,0,1,47 and each passage of the loop I change the center of the image view to space them out.
I am always using 0 as the origin.y
The problem is the origin reference is in the centre of the image view, assuming we was in interface builder, this is equivalent to the image below.
How can I change the reference point in code ?
After reading these answers and your comments I'm not really sure what is your point.
With UIView you can set position by 2 ways:
center – It definitely says it is the center.
frame.origin – Top left corner, can't be set directly.
If you want the bottom left corner to be at x=300, y=300 you can just do this:
UIView *view = ...
CGRect frame = view.frame;
frame.origin.x = 300 - frame.size.width;
frame.origin.y = 300 - frame.size.height;
view.frame = frame;
But if you go one level deeper to magical world of CALayers (don' forget to import QuartzCore), you are more powerful.
CALayer has these:
position – You see, it don't explicitely says 'center', so it may not be center!
anchorPoint – CGPoint with values in range 0..1 (including) that specifies point inside the view. Default is x=0.5, y=0.5 which means 'center' (and -[UIView center] assumes this value). You may set it to any other value and the position property will be applied to that point.
Example time:
You have a view with size 100x100
view.layer.anchorPoint = CGPointMake(1, 1);
view.layer.position = CGPointMake(300, 300);
Top left corner of the view is at x=200, y=200 and its bottom right corner is at x=300, y=300.
Note: When you rotate the layer/view it will be rotated around the anchorPoint, that is the center by default.
Bu since you just ask HOW to do specific thing and not WHAT you want to achieve, I can't help you any further now.
The object's frame includes its position in its superview. You can change it with something like:
CGRect frame = self.imageView.frame;
frame.origin.y = 0.0f;
self.imageView.frame = frame;
If I am understanding you correctly, you need to set the frame of the image view you are interested in moving. This can be done in the simple case like this:
_theImageView.frame = CGRectMake(x, y, width, height);
Obviously you need to set x, y, width, and height yourself. Please also be aware that a view's frame is in reference to its parent view. So, if you have a view that is in the top left corner (x = 0, y = 0), and is 320 points wide and 400 points tall, and you set the frame of the image view to be (10, 50, 100, 50) and then add it as a subview of the previous view, it will sit at x = 10, y = 50 of the parent view's coordinate space, even though the bounds of the image view are x = 0, y = 0. Bounds are in reference to the view itself, frame is in reference to the parent.
So, in your scenario, your code might look something like the following:
CGRect currentFrame = _theImageView.frame;
currentFrame.origin.x = 0;
currentFrame.origin.y = 0;
_theImageView.frame = currentFrame;
[_parentView addSubview:_theImageView];
Alternatively, you can say:
CGRect currentFrame = _theImageView.frame;
_theImageView.frame = CGRectMake(0, 0, currentFrame.size.width, currentFrame.size.height);
[_parentView addSubview:_theImageView];
Either approach will set the image view to the top left of the parent you add it to.
I thought I would take a cut at this in Swift.
If one would like to set a views position on the screen by specifying the coordinates to an origin point in X and Y for that view, with a little math, we can figure out where the center of the view needs to be in order for the origin of the frame to be located as desired.
This extension uses the frame of the view to get the width and height.
The equation to calculate the new center is almost trivial. See the below extension :
extension CGRect {
// Created 12/16/2020 by Michael Kucinski for anyone to reuse as desired
func getCenterWhichPlacesFrameOriginAtSpecified_X_and_Y_Coordinates(x_Position: CGFloat, y_Position: CGFloat) -> CGPoint
{
// self is the CGRect
let widthDividedBy2 = self.width / 2
let heightDividedBy2 = self.height / 2
// Calculate where the center needs to be to place the origin at the specified x and y position
let desiredCenter_X = x_Position + widthDividedBy2
let desiredCenter_Y = y_Position + heightDividedBy2
let calculatedCenter : CGPoint = CGPoint(x: desiredCenter_X, y: desiredCenter_Y)
return calculatedCenter // Using this point as the center will place the origin at the specified X and Y coordinates
}
}
Usage as shown below to place the origin in the upper left corner area, 25 pixels in :
// Set the origin for this object at the values specified
maskChoosingSlider.center = maskChoosingSlider.frame.getCenterWhichPlacesFrameOriginAtSpecified_X_and_Y_Coordinates(x_Position: 25, y_Position: 25)
If you want to pass a CGPoint into the extension instead of X and Y coordinates, that's an easy change you can make on your own.
I have a round image that I want to "squish" vertically so that it looks more like a horizontal line, then expand it back to the original shape. I thought this would work by setting the layer's anchor point to the center and then animating the frame via UIViewAnimation with the height of the frame = 1.
[self.imageToSquish.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y, self.imageToSquish.frame.size.width, 1 );
[UIView animateWithDuration:3
animations:^{self.imageToSquish.frame = newFrame;}
completion:nil];
But the image shrinks toward the top instead of around the center.
You’re giving it a frame that has its origin—at the top left—in the same position as it started. You probably want to do something more like this, adding half the image’s height:
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y + self.imageToSquish.frame.size.height / 2, self.imageToSquish.frame.size.width, 1);
Alternatively—and more efficiently—you could set the image view’s transform property to, say, CGAffineTransformMakeScale(1, 0.01) instead of messing with its frame. That’ll be centered on the middle of the image, and you can easily undo it by setting the transform to CGAffineTransformIdentity.