The point you specified for the setFocusPointOfInterest: function is invalid. This is the reason it is crumbling.
Add this method to your program and use the value returned by this function
- (CGPoint)convertToPointOfInterestFromViewCoordinates:(CGPoint)viewCoordinates { CGPoint pointOfInterest = CGPointMake(.5f, .5f); CGSize frameSize = [[self videoPreviewView] frame].size; AVCaptureVideoPreviewLayer *videoPreviewLayer = [self prevLayer]; if ([[self prevLayer] isMirrored]) { viewCoordinates.x = frameSize.width - viewCoordinates.x; } if ( [[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResize] ) { pointOfInterest = CGPointMake(viewCoordinates.y / frameSize.height, 1.f - (viewCoordinates.x / frameSize.width)); } else { CGRect cleanAperture; for (AVCaptureInputPort *port in [[[[self captureSession] inputs] lastObject] ports]) { if ([port mediaType] == AVMediaTypeVideo) { cleanAperture = CMVideoFormatDescriptionGetCleanAperture([port formatDescription], YES); CGSize apertureSize = cleanAperture.size; CGPoint point = viewCoordinates; CGFloat apertureRatio = apertureSize.height / apertureSize.width; CGFloat viewRatio = frameSize.width / frameSize.height; CGFloat xc = .5f; CGFloat yc = .5f; if ( [[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResizeAspect] ) { if (viewRatio > apertureRatio) { CGFloat y2 = frameSize.height; CGFloat x2 = frameSize.height * apertureRatio; CGFloat x1 = frameSize.width; CGFloat blackBar = (x1 - x2) / 2; if (point.x >= blackBar && point.x <= blackBar + x2) { xc = point.y / y2; yc = 1.f - ((point.x - blackBar) / x2); } } else { CGFloat y2 = frameSize.width / apertureRatio; CGFloat y1 = frameSize.height; CGFloat x2 = frameSize.width; CGFloat blackBar = (y1 - y2) / 2; if (point.y >= blackBar && point.y <= blackBar + y2) { xc = ((point.y - blackBar) / y2); yc = 1.f - (point.x / x2); } } } else if ([[videoPreviewLayer videoGravity] isEqualToString:AVLayerVideoGravityResizeAspectFill]) { if (viewRatio > apertureRatio) { CGFloat y2 = apertureSize.width * (frameSize.width / apertureSize.height); xc = (point.y + ((y2 - frameSize.height) / 2.f)) / y2; yc = (frameSize.width - point.x) / frameSize.width; } else { CGFloat x2 = apertureSize.height * (frameSize.height / apertureSize.width); yc = 1.f - ((point.x + ((x2 - frameSize.width) / 2)) / x2); xc = point.y / frameSize.height; } } pointOfInterest = CGPointMake(xc, yc); break; } } } return pointOfInterest; }
source share