我不确定我是否正确理解了你的意思,但这是我的结果:
(点击视频观看完整版本)
注:该gif图片可能需要加载一段时间。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImageView *theImageView = [UIImageView new];
[self.view addSubview:theImageView];
theImageView.image = [UIImage imageNamed:@"image1.jpg"];
theImageView.frame = self.view.frame;
theImageView.userInteractionEnabled = YES;
theImageView.alpha = 0.6;
UIImageView *thePanImageView = [UIImageView new];
[self.view addSubview:thePanImageView];
thePanImageView.frame = CGRectMake(0, 0, 100, 100);
thePanImageView.center = CGPointMake(theImageView.frame.size.width/2, theImageView.frame.size.height/2);
thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
thePanImageView.userInteractionEnabled = YES;
thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
thePanImageView.clipsToBounds = YES;
thePanImageView.theWeakObject = theImageView;
{
UIPanGestureRecognizer *thePanGesture = [UIPanGestureRecognizer new];
[thePanGesture addTarget:self action:@selector(handlePanGesture:)];
[thePanImageView addGestureRecognizer:thePanGesture];
UIPinchGestureRecognizer *thePinchGesture = [UIPinchGestureRecognizer new];
[thePinchGesture addTarget:self action:@selector(handlePinchGesture:)];
[thePanImageView addGestureRecognizer:thePinchGesture];
}
}
- (void)handlePanGesture:(UIPanGestureRecognizer *)thePanGesture
{
UIImageView *thePanImageView = (id)thePanGesture.view;
UIImageView *theImageView = thePanImageView.theWeakObject;
thePanImageView.center = [thePanGesture locationInView:theImageView];
thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)thePinchGesture
{
UIImageView *thePanImageView = (id)thePinchGesture.view;
static CGRect theInitialFrame;
if (thePinchGesture.state == UIGestureRecognizerStateBegan)
{
theInitialFrame = thePanImageView.frame;
}
else
{
CGRect theFrame = theInitialFrame;
theFrame.size.width *= thePinchGesture.scale;
theFrame.size.height *= thePinchGesture.scale;
thePanImageView.frame = theFrame;
}
thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
UIImageView *theImageView = thePanImageView.theWeakObject;
thePanImageView.center = [thePinchGesture locationInView:theImageView];
thePanImageView.image = [self screenshotFromRect:thePanImageView.frame fromView:theImageView];
}
- (UIImage * __nonnull)screenshotFromRect:(CGRect)theRect fromView:(UIView * __nonnull)theView;
{
if (!theView)
{
abort();
}
if (theRect.size.height < 1 || theRect.size.width < 1)
{
abort();
}
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
{
UIGraphicsBeginImageContextWithOptions(theRect.size, YES, [UIScreen mainScreen].scale);
}
else
{
UIGraphicsBeginImageContext(theRect.size);
}
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -theRect.origin.x, -theRect.origin.y);
[theView.layer renderInContext:ctx];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
编辑:
以上解决方案在CPU方面效率低下,因为它每次移动视图时都会截屏。
一个更加高效的方法是创建一个额外的UIImageView
,并将其简单地移动到thePanImageView
内部。
代码如下:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIImageView *theImageView = [UIImageView new];
[self.view addSubview:theImageView];
theImageView.image = [UIImage imageNamed:@"image1.jpg"];
theImageView.frame = self.view.frame;
theImageView.userInteractionEnabled = YES;
theImageView.alpha = 0.6;
UIImageView *thePanImageView = [UIImageView new];
[self.view addSubview:thePanImageView];
thePanImageView.frame = CGRectMake(0, 0, 100, 100);
thePanImageView.center = CGPointMake(theImageView.frame.size.width/2, theImageView.frame.size.height/2);
thePanImageView.userInteractionEnabled = YES;
thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
thePanImageView.clipsToBounds = YES;
thePanImageView.layer.borderColor = [UIColor redColor].CGColor;
thePanImageView.layer.borderWidth = 1;
thePanImageView.theWeakObject = theImageView;
{
UIPanGestureRecognizer *thePanGesture = [UIPanGestureRecognizer new];
[thePanGesture addTarget:self action:@selector(handlePanGesture:)];
[thePanImageView addGestureRecognizer:thePanGesture];
UIPinchGestureRecognizer *thePinchGesture = [UIPinchGestureRecognizer new];
[thePinchGesture addTarget:self action:@selector(handlePinchGesture:)];
[thePanImageView addGestureRecognizer:thePinchGesture];
UIImageView *theExtraImageView = [UIImageView new];
[thePanImageView addSubview:theExtraImageView];
theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theImageView.frame.size.width, theImageView.frame.size.height);
theExtraImageView.image = theImageView.image;
}
}
- (void)handlePanGesture:(UIPanGestureRecognizer *)thePanGesture
{
UIImageView *thePanImageView = (id)thePanGesture.view;
UIImageView *theImageView = thePanImageView.theWeakObject;
thePanImageView.center = [thePanGesture locationInView:theImageView];
UIImageView *theExtraImageView = thePanImageView.subviews.firstObject;
theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theExtraImageView.frame.size.width, theExtraImageView.frame.size.height);
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)thePinchGesture
{
UIImageView *thePanImageView = (id)thePinchGesture.view;
static CGRect theInitialFrame;
if (thePinchGesture.state == UIGestureRecognizerStateBegan)
{
theInitialFrame = thePanImageView.frame;
}
else
{
CGRect theFrame = theInitialFrame;
theFrame.size.width *= thePinchGesture.scale;
theFrame.size.height *= thePinchGesture.scale;
thePanImageView.frame = theFrame;
}
thePanImageView.layer.cornerRadius = thePanImageView.frame.size.width/2;
UIImageView *theImageView = thePanImageView.theWeakObject;
thePanImageView.center = [thePinchGesture locationInView:theImageView];
UIImageView *theExtraImageView = thePanImageView.subviews.firstObject;
theExtraImageView.frame = CGRectMake(-thePanImageView.frame.origin.x, -thePanImageView.frame.origin.y, theExtraImageView.frame.size.width, theExtraImageView.frame.size.height);
}
注意:
theWeakObject
是我自己添加到 NSObject
的自定义属性。我这样做是因为我比较懒,不想创建全局可见的 @property
。