我仍然是iOS新手,但我无法弄清楚为什么这不起作用。
我有2个单独的UIImageView的
我要做的是创建一个与“Mask Image”的当前位置/旋转/比例相匹配的CGPath
这是我的代码,用于抓取“蒙版图像”的位置并创建一个CGPAth用作图层蒙版。
如果您转到Xcode并创建一个新的“单一视图应用程序”项目,这里是ViewController的完整复制粘贴
ViewController.h:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UIGestureRecognizerDelegate>
{
UIImageView *makskedImageView;
UIImageView *maskImageView;
}
@end
ViewController.m
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *sourceImage = [UIImage imageNamed:@"forest.jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, (sourceImage.size.width/2), (sourceImage.size.height/2))];
imageView.image = sourceImage;
[self.view addSubview:imageView];
makskedImageView = imageView;
// Movable Mask
UIImage *frameBorder = [UIImage imageNamed:@"semiTransSquare.png"];
maskImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, (frameBorder.size.width/2), (frameBorder.size.height/2))];
maskImageView.image = frameBorder;
UIPanGestureRecognizer *panGesture2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGesture2 setDelegate:self];
[maskImageView addGestureRecognizer:panGesture2];
UIPinchGestureRecognizer *pinchGesture2 = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[pinchGesture2 setDelegate:self];
[maskImageView addGestureRecognizer:pinchGesture2];
UIRotationGestureRecognizer *rotateGesture2 = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotate:)];
[rotateGesture2 setDelegate:self];
[maskImageView addGestureRecognizer:rotateGesture2];
UITapGestureRecognizer *tapGR =[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
[tapGR setDelegate:self];
[tapGR setNumberOfTapsRequired:1];
[maskImageView addGestureRecognizer:tapGR];
[maskImageView setUserInteractionEnabled:YES];
// Add to view to make visible;
[self.view addSubview:maskImageView];
// apply layer mask to makskedImageView
[self grabTransform:maskImageView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)grabTransform:(UIView *)currentView
{
// build the transform you want
CGAffineTransform t = CGAffineTransformIdentity;
CGFloat angle = [(NSNumber *)[currentView valueForKeyPath:@"layer.transform.rotation.z"] floatValue];
CGFloat scale = [(NSNumber *)[currentView valueForKeyPath:@"layer.transform.scale"] floatValue];
t = CGAffineTransformConcat(t, CGAffineTransformMakeScale(scale, scale));
t = CGAffineTransformConcat(t, CGAffineTransformMakeRotation(angle));
NSLog(@"angle: %f, scale: %f", angle, scale);
// Create a mask layer
// Create a mask layer and the frame to determine what will be visible in the view.
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
// CGRect maskRect = currentView.bounds;
// Frame works a lot better.
CGRect maskRect = currentView.frame;
maskRect.origin.x = currentView.frame.origin.x;
maskRect.origin.y = currentView.frame.origin.y;
// Make a Path friendly transform.
CGPoint center = CGPointMake(CGRectGetMidX(currentView.frame), CGRectGetMidY(currentView.frame));
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, center.x, center.y);
transform = CGAffineTransformScale(transform, scale, scale);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform, -center.x, -center.y);
// Create a path and from the rectangle in it.
CGPathRef path = CGPathCreateWithRect(maskRect, &transform);
// Set the path to the mask layer.
[maskLayer setPath:path];
// Release the path since it's not covered by ARC.
CGPathRelease(path);
// Set the mask of the view.
makskedImageView.layer.mask = maskLayer;
}
#pragma mark - Gestures
-(void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
[self grabTransform:[recognizer view]];
}
-(void)handlePinch:(UIPinchGestureRecognizer *)recognizer
{
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
[self grabTransform:[recognizer view]];
}
-(void)handleRotate:(UIRotationGestureRecognizer *)recognizer
{
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
recognizer.rotation = 0;
valueForKeyPath:@"layer.transform.rotation"] floatValue];
[self grabTransform:[recognizer view]];
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (void)handleTap:(UIGestureRecognizer *)recognizer
{
[self grabTransform:[recognizer view]];
}
@end
加2张图片:Forest.jpg&amp; semiTransSquare.png
现在,当它运行时,它可用于平移,直到我缩放。旋转图像。 (由于其他一些代码,现在轮流工作)。
据我所知,尺度与中心一起作为它生长/收缩的点,其中路径似乎从根x,y坐标向外扩展。
这可能是设计的(CGPathCreateWithRect per the docs),但我看不到将变换应用于CGPath的方法,并让它出现在与UIImageView“Mask Image”相同的位置
性能是一个大问题,CIImage的类似解决方案非常滞后,所以想要在CGPath创建层掩码的情况下解决这个问题,如果可能的话,或者同样快的东西。
我错过了什么?仅适用于iOS 6解决方案。
更新:我发现从界限到帧的变化让我获得90%的胜利:
CGRect maskRect = currentView.frame;
路径现在将匹配视图的旋转和位置。剩下的唯一问题是规模是错误的。它匹配原始大小,但如果你缩小,那么它会变得太小,或者如果你长大,它会变得太大。看起来比例不是1:1。现在这么近了。
答案 0 :(得分:0)
您是否看过该功能
CGPathCreateCopyByTransformingPath
?
它需要CGRect
和仿射变换才能实现您的目标。
仅供参考,它是iOS 5 +
答案 1 :(得分:0)
您可以使用以下方式获取有效比例因子:
CGFloat zoomScale = sqrtf( powf(currentView.transform.a, 2) + powf(currentView.transform.c, 2) );
不等于:
CGFloat scale = [(NSNumber *)[currentView valueForKeyPath:@"layer.transform.scale"] floatValue];