如何在Objective-C中创建相机视图并显示后置摄像头实时画面
在Objective-C中创建仅显示后置摄像头的实时视图
我来一步步帮你搞定这个需求,从Storyboard的界面设置到ViewController的代码实现,细节都给你讲清楚:
第一步:Storyboard中的操作
- 先拖一个
UIView到你的ViewController界面上,这个view就是用来承载相机实时画面的容器。给它设置好约束(比如铺满整个屏幕,或者你想要的固定大小)。 - 给这个UIView绑定一个IBOutlet,命名为
previewView,方便后续代码里引用它。 - 关键提醒:一定要在
Info.plist里添加相机权限描述——新增NSCameraUsageDescription键,值填类似“需要访问相机来显示实时画面”的说明,不然App运行时会直接崩溃。
第二步:ViewController中的代码实现
相机功能依赖AVFoundation框架,所以我们要基于这个框架来写逻辑:
1. 声明必要的属性
在ViewController的.h或者.m的@interface里添加:
#import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> @interface ViewController : UIViewController @property (nonatomic, strong) AVCaptureSession *captureSession; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer; @property (weak, nonatomic) IBOutlet UIView *previewView; @end
2. 实现后置相机的初始化逻辑
在.m文件里写一个专门的方法来配置相机:
- (void)setupBackCamera { // 1. 创建捕获会话,这是相机功能的核心管理对象 self.captureSession = [[AVCaptureSession alloc] init]; // 设置分辨率,这里选1280x720,你可以根据需求换成更高或更低的预设 if ([self.captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) { self.captureSession.sessionPreset = AVCaptureSessionPreset1280x720; } // 2. 明确获取后置摄像头设备 AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack]; if (!backCamera) { NSLog(@"设备没有后置摄像头"); return; } // 3. 创建相机输入对象 NSError *error = nil; AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error]; if (error) { NSLog(@"创建相机输入失败:%@", error.localizedDescription); return; } // 4. 将输入添加到捕获会话 if ([self.captureSession canAddInput:videoInput]) { [self.captureSession addInput:videoInput]; } // 5. 创建预览层,把相机画面渲染到我们的previewView上 self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession]; self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // 保持比例填充容器 self.previewLayer.frame = self.previewView.bounds; [self.previewView.layer addSublayer:self.previewLayer]; // 6. 启动会话(放在全局队列,避免阻塞主线程) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self.captureSession startRunning]; }); }
3. 在页面加载时处理权限并初始化相机
- (void)viewDidLoad { [super viewDidLoad]; // 先请求相机权限,用户授权后再初始化相机 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { dispatch_async(dispatch_get_main_queue(), ^{ if (granted) { [self setupBackCamera]; } else { // 权限被拒绝,给用户提示 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"权限提示" message:@"需要相机权限才能显示实时画面,请在设置中开启" preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]]; [self presentViewController:alert animated:YES completion:nil]; } }); }]; }
4. 页面销毁时停止会话(避免资源浪费)
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if (self.captureSession.isRunning) { [self.captureSession stopRunning]; } }
额外注意事项
- 测试必须用真机,模拟器没有真实的相机硬件,无法运行这段代码。
- 如果需要处理相机的帧数据(比如实时滤镜、人脸识别),可以添加
AVCaptureVideoDataOutput并实现AVCaptureVideoDataOutputSampleBufferDelegate协议。 - 确保你的Target已经关联了
AVFoundation.framework,现在Xcode一般会自动关联,若报错可手动在Build Phases的Link Binary With Libraries里添加。
内容的提问来源于stack exchange,提问作者fi12
相关产品推荐
相关产品推荐

