使用 UIPanGestureRecognizer 的可拖动视图中的操作元素导致视图移动

Posted

技术标签:

【中文标题】使用 UIPanGestureRecognizer 的可拖动视图中的操作元素导致视图移动【英文标题】:Action Elements in a draggable view using UIPanGestureRecognizer causes the view to shift 【发布时间】:2015-04-08 10:12:07 【问题描述】:

我想创建一个包含许多动作元素的可拖动视图。为此,我通过 Apple 文档复制了代码,用于从 here 创建可拖动视图。

视图按预期平移,但当单击操作元素时,视图会转移到其他位置。这是用于复制问题的示例代码和 Main.storyboard 的屏幕截图。

ViewController.h 文件

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

- (IBAction)segmentedAction:(id)sender;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentOutlet;
@property (weak, nonatomic) IBOutlet UILabel *label;

@end

这是 ViewController.m 文件中的代码

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer

    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) 
        UIView *piece = gestureRecognizer.view;
        CGPoint locationInView = [gestureRecognizer locationInView:piece];
        CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
        
        piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
        piece.center = locationInSuperview;
    

- (IBAction)panPiece:(UIPanGestureRecognizer *)gestureRecognizer

    UIView *piece = [gestureRecognizer view];
    
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
    
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) 
        CGPoint translation = [gestureRecognizer translationInView:self.view];
        
        [piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y + translation.y)];
        [gestureRecognizer setTranslation:CGPointZero inView:self.view];
    

- (IBAction)segmentedAction:(id)sender 
    self.label.text = [NSString stringWithFormat:@"%ld",self.segmentOutlet.selectedSegmentIndex];

@end

谁能指导我在这里做错了什么。

提前致谢

【问题讨论】:

您是否要在平移手势上移动一组控件?以及向哪个视图添加了平移手势? 平移手势被添加到包含分段控件和标签的视图中,是的,我想移动视图和其中包含的所有元素 这种行为不是因为触摸了操作项,而是当您在标签上设置文本时发生。注释行“self.label.text = [NSString stringWithFormat:@"%ld",self.segmentOutlet.selectedSegmentIndex];"将解决问题。但我不知道为什么会这样。 【参考方案1】:

好的,终于找到问题了。这是由于自动布局而发生的。当您尝试设置标签的文本时,自动布局会强制视图框架重置为初始值。由于您更改了锚点,它似乎会移动到某个随机位置。

要解决此问题,只需在 viewDidLoad 方法中使用以下行;

self.label.translatesAutoresizingMaskIntoConstraints = YES;

或在adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 方法中在UIView *piece = gestureRecognizer.view; 下方添加以下行:-

piece.translatesAutoresizingMaskIntoConstraints = YES;

干杯!:-)

【讨论】:

以上是关于使用 UIPanGestureRecognizer 的可拖动视图中的操作元素导致视图移动的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 UIPanGestureRecognizer 移动对象时会有延迟?

UIPanGestureRecognizer ***视图未获取事件,子视图使用它们

在 UITableView 上滑动删除以使用 UIPanGestureRecognizer

在 UIPanGestureRecognizer 中使用velocityInView

使用 UIPanGestureRecognizer 拖动 + 旋转触摸下车

使用 UIPanGestureRecognizer 移动和缩放 UIView