I can't get a CGAffineTransform transformation to expand a view in a table cell and cannot understand why.
Can anyone see what is wrong. Here is my code:
UIView* resizedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
[resizedView addSubview:view];
[cell addSubview:view];
CGSize sizeDifference = CGSizeMake(resizedView.frame.size.width - view.frame.size.width, view.frame.size.height - view.frame.size.height);
NSLog(#"width = %f, height = %f", sizeDifference.width, sizeDifference.height);
CGSize transformRatio = CGSizeMake(resizedView.frame.size.width / view.frame.size.width, view.frame.size.height / view.frame.size.height);
// Original transform
CGAffineTransform transform = CGAffineTransformIdentity;
// Scale custom view so image will fill entire cell
transform = CGAffineTransformScale(transform, transformRatio.width, transformRatio.height);
// Move custom view so the old vie's top left aligns with the cell's top left
transform = CGAffineTransformTranslate(transform, -sizeDifference.width / 2.0, -sizeDifference.height / 2.0);
[resizedView setTransform:transform];
The view remains exactly the same. Would appreciate any suggestions.
Related
I want to rotate image with some angle as show in the below image.
I am trying to with that
CGAffineTransform t = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
imageView.transform = t;
I am not getting output like this. even I am not close with this.
Here is the code I used to rotate an image by 30 degrees
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 20, 320, 400)];
imgView.image = [UIImage imageNamed:#"maxresdefault.jpg"];
[self.view addSubview:imgView];
float degrees = 30.0f;
float radians = (degrees* M_PI/180);
imgView.layer.transform = CATransform3DMakeRotation(radians, 0, 0, 1.0);
The Simulator ScreenShot before transform
Here is the Simulator ScreenShot after Transform
Hope this helps you out.
Reset by transform before apply other transforms...
imageView.transform = CGAffineTransformIdentity
// i hope your angle is proper calculate
CGAffineTransform t = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(degrees));
imageView.transform = t;
Hope it will help you
You can change the layer.transform like below in swift
imageView?.layer.transform = CATransform3DMakeAffineTransform(CGAffineTransform(rotationAngle: CGFloat(M_PI_2)))
For Objective C :
imageView.layer.transform = CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(M_PI_2));
How can I create progressView with width 100 and height 200. And rotate progressView on 90 degrees?
It does not work together.
Or progressView is turned by 90 or change size
self.progressView.transform = CGAffineTransformMakeRotation(M_PI_2);
CGAffineTransform transform = CGAffineTransformMakeScale(1.0f, 3.0f);
_progressView.transform = transform;
You need to chain your transformations. In your sample, the 2nd assignment to transform effectively overwrites the first one. This one works:
UIProgressView *progressBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
progressBar.frame = CGRectMake(50, 100, 100, 50);
CGAffineTransform t = CGAffineTransformMakeRotation(M_PI_2);
t = CGAffineTransformScale(t, 1.0f, 50.0f);
progressBar.transform = t;
[self.view addSubview:progressBar];
I read about that somewhere...I think CGAffineTransform() works for that
[self.progressView setTransform:CGAffineTransformMakeScale(1.0, 2.0)];
For rotation
#define DEGREES_TO_RADIANS(angle) ((90) / 180.0 * M_PI)
[self.progressView setTransform:CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(angle))];
Swift 4
progressView.transform = CGAffineTransform(scaleX: 1.0, y: 2.0)
I am trying to create a custom animation something like the default flip animation for a UIView, but without the actual flip, and also the axis of the flip I want to be on the left side not on the center. Here is an example of what I am trying to accomplish but without the repeat:
Also in the code I will add UILabel as sub view and a few more elements.
If you can provide a code example it will be much appreciated
Thank you very much in advance for any support!
Update:
used the example provided by #artal and obtained the wanted effect for UIImageView but how can I obtain the same example for an UIButton?
Tried the next code:
objectivesButton = [[UIButton alloc] initWithFrame:CGRectMake( 0.25f * [UIScreen mainScreen].bounds.size.width, 0.7f * [UIScreen mainScreen].bounds.size.height, 0.5f * [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height * 0.3f)];
[objectivesButton addTarget:self
action:#selector(startAnimationButton)
forControlEvents:UIControlEventTouchUpInside];
objectivesButton.backgroundColor = [UIColor yellowColor];
objectivesButton.layer.anchorPoint = CGPointMake(0, 0.5);
[self.view addSubview:objectivesButton];
- (void)startAnimationButton{
CATransform3D perspectiveTrasnform = CATransform3DIdentity;
perspectiveTrasnform.m34 = -0.004;
CGFloat rotateAngleDeg = 90;
CATransform3D flipTransform = CATransform3DRotate(perspectiveTrasnform, rotateAngleDeg / 180.0 * M_PI, 0, 1.5, 0);
[UIView animateWithDuration:3.0f animations:^()
{
objectivesButton.layer.transform = flipTransform;
}];
}
You can animate the view this way by applying a perspective and rotation transform to its underlying CALayer (a 3D transform).
To start it from the left side you can set the anchorPoint of the layer.
Here's an example:
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
imageView.center = CGPointMake(self.view.center.x - imageView.frame.size.width * 0.5, self.view.center.y + imageView.frame.size.height * 0.5);
imageView.layer.anchorPoint = CGPointMake(0, 1);
[self.view addSubview:imageView];
CATransform3D perspectiveTrasnform = CATransform3DIdentity;
perspectiveTrasnform.m34 = -0.004;
CGFloat rotateAngleDeg = 90;
CATransform3D flipTransform = CATransform3DRotate(perspectiveTrasnform, rotateAngleDeg / 180.0 * M_PI, 0, 1, 0);
[UIView animateWithDuration:5 animations:^()
{
imageView.layer.transform = flipTransform;
}];
Similar to Instagram I have a square crop view (UIScrollView) that has a UIImageView inside it. So the user can drag a portrait or landscape image inside the square rect (equal to the width of the screen) and then the image should be cropped at the scroll offset. The UIImageView is set to aspect fit. The UIScrollView content size is set to a scale factor for either landscape or portrait, so that it correctly renders with aspect fit ratio.
When the user is done dragging I want to scale the image up based on a given size, let's say 1000x1000px square and then crop it at the scroll offset (using [UIImage drawAtPoint:CGPoint].
The problem is I can't get the math right to get the right offset point. If I get it close on a 6+ it will be way off on a 4S.
Here's my code for the scale and crop:
(UIImage *)squareImageFromImage:(UIImage *)image scaledToSize:(CGFloat)newSize {
CGAffineTransform scaleTransform;
CGPoint origin;
if (image.size.width > image.size.height) {
//landscape
CGFloat scaleRatio = newSize / image.size.height;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake((int)(-self.scrollView.contentOffset.x*scaleRatio),0);
} else if (image.size.width < image.size.height) {
//portrait
CGFloat scaleRatio = newSize / image.size.width;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(0, (int)(-self.scrollView.contentOffset.y*scaleRatio));
} else {
//square
CGFloat scaleRatio = newSize / image.size.width;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(0, 0);
}
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, scaleTransform);
[image drawAtPoint:origin];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
So for example with landscape, if I drag the scroll left so that the image is cropped all the way to the right, my offset will be close on a 6+ but on a 4S it will be off by about 150-200 in terms of the CGPoint.
Here is my code for setting up the scroll view and image view:
CGRect cropRect = CGRectMake(0.0f,0.0,SCREEN_WIDTH,SCREEN_WIDTH);
CGFloat ratio = (int)self.image.size.height/self.image.size.width;
CGRect r = CGRectMake(0.0,0.0,SCREEN_WIDTH,SCREEN_WIDTH);
if (ratio>1.00) {
//portrait
r = CGRectMake(0.0,0.0,SCREEN_WIDTH,(int)(SCREEN_WIDTH*ratio));
} else if (ratio<1.00) {
//landscape
CGFloat size = (int)self.image.size.width/self.image.size.height;
cropOffset = (SCREEN_WIDTH*size)-SCREEN_WIDTH;
r = CGRectMake(0.0,0.0,(int)(SCREEN_WIDTH*size),SCREEN_WIDTH);
}
NSLog(#"r.size.height == %.4f",r.size.height);
self.scrollView.frame = cropRect;
self.scrollView.contentSize = r.size;
self.imageView = [[UIImageView alloc] initWithFrame:r];
self.imageView.backgroundColor = [UIColor clearColor];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = self.image;
[self.scrollView addSubview:self.imageView];
Cropping math can be tricky. It's been a while since I've had to deal with this, so hopefully I'm pointing you in the right direction. Here is a chunk of code from Pixology that grabs a scaled visible rect from a UIScrollView. I think the missing ingredient here might be zoomScale.
CGRect visibleRect;
visibleRect.origin = _scrollView.contentOffset;
visibleRect.size = _scrollView.bounds.size;
// figure in the scale
float theScale = 1.0 / _scrollView.zoomScale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;
You may also need to figure in device screen scale:
CGFloat screenScale = [[UIScreen mainScreen] scale];
See how far you can get with this info, and let me know.
I have a question about scale operation of a frame to a specific size.
I have a CGRect and would to resize it to a specific CGSize.
I would to move the center of this CGRect in proportion to my rescale value.
If by chance you're modifying a UIView, you could take this approach:
CGPoint previousCenter = view.center;
// Set width and height here:
view.frame = CGRectMake(view.frame.origin.x,view.frame.origin.y, width, height);
view.center = previousCenter;
That'll maintain the center point while changing the size of the view.
I am a little confused by your question, so I may not be answering it correctly. If you are using a CGAffineTransform to scale, as your tags suggest, that's another matter entirely.
You can use CGRectInset(rect, x, y). This will inset the CGRect by x and y, and push the origin in by x and y. (https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html#//apple_ref/c/func/CGRectInset)
CGSize targetSize = CGSizeMake(100.0f, 100.0f);
CGRect rect = CGRectMake(50.0f, 50.0f, 200.0f, 200.0f);
rect = CGRectInset(rect, roundf((rect.size.width - targetSize.width) / 2.0f), roundf((rect.size.height - targetSize.height) / 2.0f);
Edit: Note that I'm using the difference between the two sizes, halved. My justification here is that CGRectInset will affect the entire rect. What I mean by that is...
CGRect rect = CGRectMake(0, 0, 10, 10);
rect = CGRectInset(rect, 2, 2);
rect is now a CGRect with (2, 2, 6, 6)