在 UIPopoverController 中丢失手势识别器

Posted

技术标签:

【中文标题】在 UIPopoverController 中丢失手势识别器【英文标题】:Losing Gesture Recognizers in UIPopoverController 【发布时间】:2012-05-04 15:48:23 【问题描述】:

我有一个名为 PhotoBoothController 的类,我用它来使用手势操作图像。当我在 iPhone 上运行它时,它运行良好。但是,当我在 iPad 上运行它时,我会在 UIPopoverController 中显示 PhotoBoothController。图像看起来很好,但是我无法操作它,因为我的手势似乎无法被识别。我不确定如何让 UIPopoverController 控制手势。

我展示了 popovercontroller 并这样配置视图:

- (void)presentPhotoBoothForPhoto:(UIImage *)photo button:(UIButton *)button 

    //Create a photoBooth and set its contents
    PhotoBoothController *photoBoothController = [[PhotoBoothController alloc] init];
    photoBoothController.photoImage.image = [button backgroundImageForState:UIControlStateNormal];

    //set up all the elements programmatically.
    photoBoothController.view.backgroundColor = [UIColor whiteColor];

    //Add frame (static)
    UIImage *frame = [[UIImage imageNamed:@"HumptyLine1Frame.png"] adjustForResolution];
    UIImageView *frameView = [[UIImageView alloc] initWithImage:frame];
    frameView.frame = CGRectMake(50, 50, frame.size.width, frame.size.height);
    [photoBoothController.view addSubview:frameView];

    //Configure image
    UIImageView *photoView = [[UIImageView alloc] initWithImage:photo];
    photoView.frame = CGRectMake(50, 50, photo.size.width, photo.size.height);
    photoBoothController.photoImage = photoView;

    //Add canvas
    UIView *canvas = [[UIView alloc] initWithFrame:frameView.frame];
    photoBoothController.canvas = canvas;
    [canvas addSubview:photoView];
    [canvas becomeFirstResponder];

    [photoBoothController.view addSubview:canvas];
    [photoBoothController.view bringSubviewToFront:frameView];

    //resize the popover view shown in the current view to the view's size
    photoBoothController.contentSizeForViewInPopover = CGSizeMake(frameView.frame.size.width+100, frameView.frame.size.height+400);

    self.photoBooth = [[UIPopoverController alloc] initWithContentViewController:photoBoothController];
    [self.photoBooth presentPopoverFromRect:button.frame
                                     inView:self.view
                   permittedArrowDirections:UIPopoverArrowDirectionAny
                                   animated:YES];

我认为[canvas becomeFirstResponder] 可能会这样做,但似乎没有什么不同。

非常感谢任何建议,谢谢。

更新:根据评论添加代码

- (void)viewDidLoad 
  [super viewDidLoad];

  if (!_marque) 
    _marque = [CAShapeLayer layer];
    _marque.fillColor = [[UIColor clearColor] CGColor];
    _marque.strokeColor = [[UIColor grayColor] CGColor];
    _marque.lineWidth = 1.0f;
    _marque.lineJoin = kCALineJoinRound;
    _marque.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],[NSNumber numberWithInt:5], nil];
    _marque.bounds = CGRectMake(photoImage.frame.origin.x, photoImage.frame.origin.y, 0, 0);
    _marque.position = CGPointMake(photoImage.frame.origin.x + canvas.frame.origin.x, photoImage.frame.origin.y + canvas.frame.origin.y);
  
  [[self.view layer] addSublayer:_marque];

  UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
  [pinchRecognizer setDelegate:self];
  [self.view addGestureRecognizer:pinchRecognizer];

  UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
  [rotationRecognizer setDelegate:self];
  [self.view addGestureRecognizer:rotationRecognizer];

  UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
  [panRecognizer setMinimumNumberOfTouches:1];
  [panRecognizer setMaximumNumberOfTouches:1];
  [panRecognizer setDelegate:self];
  [canvas addGestureRecognizer:panRecognizer];

  UITapGestureRecognizer *tapProfileImageRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
  [tapProfileImageRecognizer setNumberOfTapsRequired:1];
  [tapProfileImageRecognizer setDelegate:self];
  [canvas addGestureRecognizer:tapProfileImageRecognizer];



- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
  return ![gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]];

【问题讨论】:

请添加用于将手势识别器附加到您的 UIPopoverController 的代码 @stavash 完成 - 代码在 PhotoBoothController 类中。谢谢! 这是一个有趣的问题。将手势从外部添加到 UIPopoverController 怎么样?我知道它需要进行很多更改,但我现在没有任何其他建议... 【参考方案1】:

我正在开发一个类似的应用程序,我可以轻松地操作画布上的图像。

1) 检查画布的 userInteractionEnabled 属性是否设置为 YES。 2)您可以尝试将手势添加到 ImageView 而不是画布。 (我猜你想缩放、旋转和滑动图像)。

【讨论】:

【参考方案2】:

一些猜测:

    这是因为 viewDidLoad 方法在设置 cavas 属性之前已被调用吗?在这种情况下,您可以尝试在当前弹出框之后以另一种方法(例如viewDidAppear)添加识别器。

    我也同意关键可能是 UIPopoverController 允许与弹出框之外的其他视图进行交互。所以我建议将[canvas becomeFirstResponder]; 移动到PhotoBoothControllerviewDidLoad 方法的末尾并在此处尝试self.view becomeFirstResponder,因为您实际上将识别器添加到self.view。

【讨论】:

以上是关于在 UIPopoverController 中丢失手势识别器的主要内容,如果未能解决你的问题,请参考以下文章

在 UIPopoverController 中显示 UIViewController

UIPopoverController 上的 UIPopoverController

在 UIPopoverController 中显示 UItableViewController

UIPopoverController 在 iOS 8 / Xcode 6 中没有关闭

在 UIPopoverController 中使用 UIImagePickerController 后播放视频消失

UIPopoverController 可以在屏幕上移动吗?