は素晴らしいスタートですが、それは私のために動作しませんでした
- (void) focus:(CGPoint) aPoint;
{
Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [captureDeviceClass defaultDeviceWithMediaType:AVMediaTypeVideo];
if([device isFocusPointOfInterestSupported] &&
[device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
CGPoint focusPoint = [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:aPoint];
if([device lockForConfiguration:nil]) {
[device setFocusPointOfInterest:CGPointMake(focusPoint.x,focusPoint.y)];
[device setFocusMode:AVCaptureFocusModeAutoFocus];
if ([device isExposureModeSupported:AVCaptureExposureModeAutoExpose]){
[device setExposureMode:AVCaptureExposureModeAutoExpose];
}
[device unlockForConfiguration];
}
}
}
}
ドキュメントはこちらです。私は、ユーザーが一度ではなくフォーカスポイントを選択できるようにしたいと思っていました(これは彼の解決策です)。私を正しい方向に向けるための@Anilに感謝します。
私の解決策にはいくつかの違いがあります。
- 私はフォーカスの広場とアニメーションを一度だけではなく再利用できるようにしたいと考えました。
- それは私が行うにはアニルのソリューション@得ることができませんでした(何かを完了した後、私は消えるためにアニメーションを望んでいた。
- 代わり
initWithFrame:
を使用して、私は私自身のinitWithTouchPoint:
を実施しました。
- 私は、特にアニメーション化するための方法を持っていますフォーカスアクション。
- は、私はまた、フレームの位置を更新するための方法を持っている。
- フレームのサイズは、必要に応じてサイズを確認し、更新する方が簡単だということを意味し、
CameraFocusSquare
以内です。
CameraFocusSquare.h
@import UIKit;
@interface CameraFocusSquare : UIView
- (instancetype)initWithTouchPoint:(CGPoint)touchPoint;
- (void)updatePoint:(CGPoint)touchPoint;
- (void)animateFocusingAction;
@end
CameraFocusSquare.m
#import "CameraFocusSquare.h"
@implementation CameraFocusSquare {
CABasicAnimation *_selectionBlink;
}
/**
This is the init method for the square. It sets the frame for the view and sets border parameters. It also creates the blink animation.
*/
- (instancetype)initWithTouchPoint:(CGPoint)touchPoint {
self = [self init];
if (self) {
[self updatePoint:touchPoint];
self.backgroundColor = [UIColor clearColor];
self.layer.borderWidth = 2.0f;
self.layer.borderColor = [UIColor orangeColor].CGColor;
// create the blink animation
_selectionBlink = [CABasicAnimation
animationWithKeyPath:@"borderColor"];
_selectionBlink.toValue = (id)[UIColor whiteColor].CGColor;
_selectionBlink.repeatCount = 3; // number of blinks
_selectionBlink.duration = 0.4; // this is duration per blink
_selectionBlink.delegate = self;
}
return self;
}
/**
Updates the location of the view based on the incoming touchPoint.
*/
- (void)updatePoint:(CGPoint)touchPoint {
CGFloat squareWidth = 50;
CGRect frame = CGRectMake(touchPoint.x - squareWidth/2, touchPoint.y - squareWidth/2, squareWidth, squareWidth);
self.frame = frame;
}
/**
This unhides the view and initiates the animation by adding it to the layer.
*/
- (void)animateFocusingAction {
// make the view visible
self.alpha = 1.0f;
self.hidden = NO;
// initiate the animation
[self.layer addAnimation:_selectionBlink forKey:@"selectionAnimation"];
}
/**
Hides the view after the animation stops. Since the animation is automatically removed, we don't need to do anything else here.
*/
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
// hide the view
self.alpha = 0.0f;
self.hidden = YES;
}
@end
Iは、ビューの上にこのすべてを開始します。これにより、柔軟性が増し、UIコードとコントローラコード(MVCと考える)が分離されます。
PreviewView.h
@import UIKit;
@interface PreviewView : UIView
- (IBAction)tapToFocus:(UITapGestureRecognizer *)gestureRecognizer;
@end
PreviewView.m
#import "PreviewView.h"
#import "CameraFocusSquare.h"
@implementation PreviewView {
CameraFocusSquare *_focusSquare;
}
- (IBAction)tapToFocus:(UITapGestureRecognizer *)gestureRecognizer {
CGPoint touchPoint = [gestureRecognizer locationOfTouch:0 inView:self];
if (!_focusSquare) {
_focusSquare = [[CameraFocusSquare alloc] initWithTouchPoint:touchPoint];
[self addSubview:_focusSquare];
[_focusSquare setNeedsDisplay];
}
else {
[_focusSquare updatePoint:touchPoint];
}
[_focusSquare animateFocusingAction];
}
@end
最後に、私のUIViewController
サブクラスで、私は私のUITapGestureRecognizer
が作成したビューに取り付けられています。ここでは、タップ・ツー・フォーカス・コードを実装しています。
CameraViewController.m
- (void)viewDidLoad {
// do other initialization stuff here
// create the tap-to-focus gesture
UITapGestureRecognizer *tapToFocusRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToFocus:)];
tapToFocusRecognizer.numberOfTapsRequired = 1;
tapToFocusRecognizer.numberOfTouchesRequired = 1;
[self.previewView addGestureRecognizer:tapToFocusRecognizer];
}
- (IBAction)tapToFocus:(UITapGestureRecognizer *)tapGestureRecognizer {
if (!_captureDevice) {
return;
}
if (![_captureDevice isFocusPointOfInterestSupported]) {
return;
}
if (![_captureDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
return;
}
[self.previewView tapToFocus:tapGestureRecognizer];
NSError *error;
[_captureDevice lockForConfiguration:&error];
if (error) {
NSLog(@"Error trying to lock configuration of camera. %@", [error localizedDescription]);
return;
}
CGPoint touchPoint = [tapGestureRecognizer locationOfTouch:0 inView:self.cameraView];
// range of touch point is from (0,0) to (1,1)
CGFloat touchX = touchPoint.x/self.previewView.frame.size.width;
CGFloat touchY = touchPoint.y/self.previewView.frame.size.height;
_captureDevice.focusMode = AVCaptureFocusModeAutoFocus;
if ([_captureDevice isExposureModeSupported:AVCaptureExposureModeAutoExpose]) {
_captureDevice.exposureMode = AVCaptureExposureModeAutoExpose;
}
_captureDevice.focusPointOfInterest = CGPointMake(touchX, touchY);
if ([_captureDevice isExposurePointOfInterestSupported]) {
_captureDevice.exposurePointOfInterest = CGPointMake(touchX, touchY);
}
[_captureDevice unlockForConfiguration];
}
は、彼らがより重要なコードの上に移動することができますので、これは人々を役に立てば幸い!
しかし、あなたは(場合 '使用する必要がありますCaptureDeviceClass!= Nil) ' –
あなたのヒントをありがとう。私は本当に気にしていないし、現在の違いについて知っているので、私はそれを見上げた。私がクラスを参照しているという事実のために、あなたは絶対に正しいです。 – Alexander
@アレクサンダー、私はあなたと同じ問題に直面しています。あなたはこの問題を解決しましたか? – ttotto