Objective c UIPopovercontroller未检测到触摸

Objective c UIPopovercontroller未检测到触摸,objective-c,ios,xcode,uipopovercontroller,Objective C,Ios,Xcode,Uipopovercontroller,我有一个UIPopoverController,它是用一个定制的视图控制器——photoBoothController初始化的 photoBoothController包含一个名为canvas的UIView。此画布包含多个手势识别器,可检测手势并执行适当的功能 问题在于,当显示UIPopoverController时,无法识别手势识别器。我通过添加一个UIButton来测试这一点。如果我将它添加为photoBoothController的子视图,我可以按它。但是,如果我将其添加为画布的子视图,我

我有一个UIPopoverController,它是用一个定制的视图控制器——photoBoothController初始化的

photoBoothController包含一个名为canvas的UIView。此画布包含多个手势识别器,可检测手势并执行适当的功能

问题在于,当显示UIPopoverController时,无法识别手势识别器。我通过添加一个UIButton来测试这一点。如果我将它添加为photoBoothController的子视图,我可以按它。但是,如果我将其添加为画布的子视图,我将无法再按它

所以我的问题是如何将手势传递到画布上?我尝试在photoBoothController的ViewDidDisplay和ViewWillDisplay方法中添加
[canvas becomeFirstResponder]
,但似乎没有什么不同。我知道代码在其他方面是合理的,因为它在作为常规视图而不是在UIPopoverController中运行时可以完美地工作

非常感谢

photoBoothController中的代码:

#import "PhotoBoothController.h"


@implementation PhotoBoothController

@synthesize canvas;
@synthesize photoImage;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - Private Methods

-(void)showOverlayWithFrame:(CGRect)frame {

  if (![_marque actionForKey:@"linePhase"]) {
    CABasicAnimation *dashAnimation;
    dashAnimation = [CABasicAnimation animationWithKeyPath:@"lineDashPhase"];
    [dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
    [dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]];
    [dashAnimation setDuration:0.5f];
    [dashAnimation setRepeatCount:HUGE_VALF];
    [_marque addAnimation:dashAnimation forKey:@"linePhase"];
  }

  _marque.bounds = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);
  _marque.position = CGPointMake(frame.origin.x + canvas.frame.origin.x, frame.origin.y + canvas.frame.origin.y);

  CGMutablePathRef path = CGPathCreateMutable();
  CGPathAddRect(path, NULL, frame);
  [_marque setPath:path];
  CGPathRelease(path);

  _marque.hidden = NO;

}

-(void)scale:(id)sender {

    if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
      _lastScale = 1.0;
    }

    CGFloat scale = 1.0 - (_lastScale - [(UIPinchGestureRecognizer*)sender scale]);

    CGAffineTransform currentTransform = photoImage.transform;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);

    [photoImage setTransform:newTransform];

    _lastScale = [(UIPinchGestureRecognizer*)sender scale];
    [self showOverlayWithFrame:photoImage.frame];
}

-(void)rotate:(id)sender {

    if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {

      _lastRotation = 0.0;
      return;
    }

    CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);

    CGAffineTransform currentTransform = photoImage.transform;
    CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);

    [photoImage setTransform:newTransform];

    _lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
    [self showOverlayWithFrame:photoImage.frame];
}


-(void)move:(id)sender {
    NSLog(@"MOVING GESTURE");

  CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:canvas];

  if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
    _firstX = [photoImage center].x;
    _firstY = [photoImage center].y;
  }

  translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y);

  [photoImage setCenter:translatedPoint];
  [self showOverlayWithFrame:photoImage.frame];
}

-(void)tapped:(id)sender {
  _marque.hidden = YES;
}


#pragma mark - View lifecycle

- (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];

}

- (void)viewWillAppear:(BOOL)animated {
    [self.canvas becomeFirstResponder];
    [super viewWillAppear:animated];
}

- (void)viewDidUnload
{
  [self setPhotoImage:nil];
  [self setCanvas:nil];
  [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return NO;
}

#pragma mark UIGestureRegognizerDelegate

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

@end
要初始化的代码:

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

    //Create frame outline image
    UIImage *outline = [[UIImage imageNamed:@"HumptyLine1Frame.png"] adjustForResolution];
    UIImageView *outlineView = [[UIImageView alloc] initWithImage:outline];
    outlineView.frame = CGRectMake(0, 0, outline.size.width, outline.size.height);

    //Create photo image. Already ajusted to resolution?
    UIImageView *photoView = [[UIImageView alloc] initWithImage:photo];
    photoView.frame = CGRectMake(0, 0, photo.size.width, photo.size.height);

    //Add done button
    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    doneButton.frame = CGRectMake(0, 0, 100, 40);
    [doneButton addTarget:self action:@selector(renderPhoto:) forControlEvents:UIControlEventTouchUpInside];
    [doneButton setTitle:@"Done" forState:UIControlStateNormal];

    //Create canvas with outline as the frame into which the image is rendered
    //Here is where I'll need to define a custom method to create a frame shaped by the outline
    UIView *canvas = [[UIView alloc] initWithFrame:outlineView.frame];
    [canvas setBackgroundColor:[UIColor blackColor]];
    [canvas addSubview:photoView];
    [canvas addSubview:doneButton];

    //Create a photoBooth and set its contents
    PhotoBoothController *photoBoothController = [[PhotoBoothController alloc] init];
    //resize the view
    photoBoothController.contentSizeForViewInPopover = CGSizeMake(canvas.frame.size.width+100, canvas.frame.size.height+50);
    photoBoothController.view.backgroundColor = [UIColor whiteColor];
    photoBoothController.canvas = canvas;
    photoBoothController.photoImage = photoView;
    [photoBoothController.view addSubview:canvas];
    //photoBoothController.view.gestureRecognizers = canvas.gestureRecognizers;

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

我想你的问题在这里

[photoBoothController.view addSubview:canvas];
[photoBoothController.view addSubview:outlineView];
您正在画布视图上添加大纲视图,两者具有相同的框架。。试试这个

[photoBoothController.view  bringSubviewToFront:canvas];
举个例子:

TestVC *test = [[TestVC alloc] initWithNibName:@"TestVC" bundle:nil];

UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[testView setBackgroundColor:[UIColor yellowColor]];

test.contentSizeForViewInPopover = CGSizeMake(testView.frame.size.width+100, testView.frame.size.height+50);

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(10, 10, 40, 40)];
[button setBackgroundColor:[UIColor redColor]];
[button addTarget:self action:@selector(sss) forControlEvents:UIControlEventTouchUpInside];

[testView addSubview:button];

[test.view addSubview:testView];

UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:test];
[popover presentPopoverFromRect:sender.bounds inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

似乎没有什么不同,只是画面后面现在有了相框。仍然不会重复任何触摸,UIButton仅在它是photoBoothController的子视图而不是画布时才起作用。。。不知何故,我需要将触摸从photoBoothController传递到画布,因为它似乎阻止了触摸?好的,尝试在不同的级别上进行。。将按钮添加到画布,将画布添加到photoBoothController.view,不要添加任何其他内容并检查其是否有效。确定尝试了此操作,但按钮仍然无效。只有当它直接添加为photoBoothController的子视图时。。。我应该以某种方式传递这些手势吗?只有我的photoBoothController符合UIgestureRecognitizerDelegate…您可以更改画布的背景色以检查按钮是否完全位于画布视图内吗?啊哈!是的,按钮在画布的范围之外,好主意。在边界内移动它会使它做出反应。但是,当我添加图像时,这些手势仍然无法识别。我应该能够平移,旋转等,它保持静止。。。