カスタム ビュー コントローラー (photoBoothController) で初期化される UIPopoverController があります。
photoBoothController には、canvas という UIView が含まれています。このキャンバスには、ジェスチャを検出して適切な機能を実行するいくつかのgestureRecognizersが含まれています。
問題は、UIPopoverController が表示されているときに、gestureRecognizers が認識されないことです。UIButton を追加してこれをテストしました。photoBoothController のサブビューとして追加すると、それを押すことができます。ただし、キャンバスのサブビューとして追加すると、押すことができなくなります。
私の質問は、ジェスチャーをキャンバスに渡すにはどうすればよいですか? photoBoothController の viewDidAppear および viewWillAppear メソッドを追加しようとし[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];
}