实现这个功能也是被逼无奈,项目需要缩放移动有很多小页签的WKWebView,尝试了UIScrollView,但是很不理想,因为webview需要侧滑和上下滑动,所以缩放拖动绝大部分都无法触发,只得采用手势实现。在网上查阅了大量资料,终于实现了该功能,废话不多说,上代码:
1、定义缩放倍数和偏移量
// 缩放倍数
#define minScale 1
#define maxScale 2
// 偏移量
#define Offset 0
2、定义需要用到的属性
@property (nonatomic,strong) UIImageView *imgView;// 要缩放的视图
// 缩放
@property (nonatomic, assign) CGFloat lastScale;// 上一次缩放的比例
@property (nonatomic, strong) UIPinchGestureRecognizer *pinch;// 捏合手势
@property (nonatomic, strong) UIPanGestureRecognizer *pan;// 平移手势
3、初始化视图、手势,并设置手势
_imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.jpg"]];
_imgView.frame = self.view.frame;
_imgView.userInteractionEnabled = YES;
[self.view addSubview:_imgView];
_pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchAction:)];
_pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[_imgView addGestureRecognizer:_pinch];
[_imgView addGestureRecognizer:_pan];
4、 设置锚点
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
//UIGestureRecognizerStateBegan意味着手势已经被识别
if (gestureRecognizer.state ==UIGestureRecognizerStateBegan)
{
//手势发生在哪个view上
UIView *piece = gestureRecognizer.view;
//获得当前手势在view上的位置。
CGPoint locationInView = [gestureRecognizer locationInView:piece];
piece.layer.anchorPoint =CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
//根据在view上的位置设置锚点。
//防止设置完锚点过后,view的位置发生变化,相当于把view的位置重新定位到原来的位置上。
CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
piece.center = locationInSuperview;
}
}
5、 缩放方法
- (void)pinchAction:(UIPinchGestureRecognizer *)gestureRecognizer{
UIGestureRecognizerState state = [gestureRecognizer state];
if(state == UIGestureRecognizerStateBegan) {
_lastScale = [gestureRecognizer scale];
}
if (gestureRecognizer.scale > 1) {
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
}else{
_imgView.layer.anchorPoint =CGPointMake(0.5, 0.5);
_imgView.center = self.view.center;
}
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
if (state == UIGestureRecognizerStateBegan ||
state == UIGestureRecognizerStateChanged) {
CGFloat newScale = 1 - (_lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, maxScale / currentScale);
newScale = MAX(newScale, minScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
NSLog(@"newScale = %f,currentScale = %f",newScale,currentScale);
[gestureRecognizer view].transform = transform;
_lastScale = [gestureRecognizer scale];
}
if (state == UIGestureRecognizerStateEnded) {
if (currentScale >= minScale && currentScale <= minScale + 0.1) {
[_imgView removeGestureRecognizer:_pan];
}else if(currentScale > minScale + 0.1 && currentScale <= maxScale){
[_imgView addGestureRecognizer:_pan];
}
}
}
6、 拖动方法
- (void)panAction:(UIPanGestureRecognizer *)gestureRecognizer{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan ||
gestureRecognizer.state == UIGestureRecognizerStateChanged) {
if (!(_imgView.frame.origin.x == 0 &&
_imgView.frame.origin.y == 0 &&
_imgView.frame.size.width == self.view.frame.size.width &&
_imgView.frame.size.height == self.view.frame.size.height)) {
CGPoint translation = [gestureRecognizer translationInView:self.view];
gestureRecognizer.view.center = CGPointMake(gestureRecognizer.view.center.x + translation.x, gestureRecognizer.view.center.y + translation.y);
[gestureRecognizer setTranslation:CGPointZero inView:self.view];
}
}
CGRect rect = _imgView.frame;
if (_imgView.frame.origin.x > 0 + Offset) {//左边进入屏幕
NSLog(@"左边进入屏幕");
[UIView animateWithDuration:0.25 animations:^{
CGPoint point = CGPointMake(gestureRecognizer.view.center.x - gestureRecognizer.view.frame.origin.x, gestureRecognizer.view.center.y);
gestureRecognizer.view.center = point;
}];
}else if (CGRectGetMaxX(rect) < self.view.frame.size.width + Offset){
NSLog(@"右边进入屏幕");
[UIView animateWithDuration:0.25 animations:^{
CGRect newRect = CGRectOffset(_imgView.frame, self.view.frame.size.width - CGRectGetMaxX(_imgView.frame), 0);
_imgView.frame = newRect;
}];
}
if (_imgView.frame.origin.y > 0 + Offset) {//上边进入屏幕
NSLog(@"上边进入屏幕");
[UIView animateWithDuration:0.25 animations:^{
CGPoint point = CGPointMake(gestureRecognizer.view.center.x, gestureRecognizer.view.center.y - gestureRecognizer.view.frame.origin.y);
gestureRecognizer.view.center = point;
}];
}else if(CGRectGetMaxY(rect) < self.view.frame.size.height + Offset){
NSLog(@"下边进入屏幕");
[UIView animateWithDuration:0.25 animations:^{
CGRect newRect = CGRectOffset(_imgView.frame, 0, self.view.frame.size.height - CGRectGetMaxY(_imgView.frame));
_imgView.frame = newRect;
}];
}
}
手势实现也是万不得已才用的,如果有哪位大神解决了UIScrollView缩放有多个侧滑页签,并且可以上下滑动的WKWebView,请给我留言,相互交流,万分感谢。
转载请注明出处,万分感谢!