我對iOS仍然很新,但我無法弄清楚爲什麼這種方式不起作用。從UIimageview創建CGpath,使用旋轉和縮放作爲cglayer掩碼使用
我有2個獨立的UIImageView的
- 的 '背景'。這是一張將應用圖層蒙版的圖片,以便您只能看到圖像的一部分。
- '面具圖像'這是它自己的獨立圖像,可以旋轉,平移,捏縮放。旋轉/縮放的代碼工作正常,並且是標準代碼。
我所要做的是創建到當前位置/旋轉/的「掩模圖像」
這裏是我抓住了「掩模圖像」的位置代碼和規模相匹配的CGPath創建一個CGPAth用作圖層蒙版。
如果你去Xcode和做一個新的 '單一視圖的應用' 項目,這裏是視圖控制器
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 & semiTransSquare.png
現在,當它運行它的作品爲平移,直到我scale.rotate圖像。 (現在旋轉工作感謝其他代碼)。
從我可以告訴規模與中心的工作作爲它成長/縮小的點,其中路徑似乎從根x,y座標伸出。
這可能是由設計(CGPathCreateWithRect per the docs),但我看不到的方式來對轉換適用於CGPath並讓它出現在同一地點的UIImageView「掩模圖像」
性能是一大問題和CIImage的類似解決方案非常滯後,所以想要在CGPath創建圖層掩碼的情況下解決這個問題,如果可能的話,或者一樣快。
我錯過了什麼?歡迎使用iOS 6解決方案。
更新:我發現,從範圍更改爲框架讓我90%的方式出現:
CGRect maskRect = currentView.frame;
的路徑,現在將匹配該視圖的旋轉和位置。剩下的唯一問題是規模是錯誤的。它匹配原始尺寸,但是如果縮小,那麼它變得太小,或者如果你長大,它會變得太大。看起來規模不是1:1。現在很近。
增加。我覺得這不會那麼難。 :-)讓我知道如果我需要用完整代碼創建一個虛擬應用程序來更清楚地顯示問題。 – Adam21e
如果你添加一個虛擬應用程序,我會仔細看看它。 – algal