環境
Flutter 3.29
macOS Sequoia 15.4.1
Xcode 16.3
iOS 13.4.1
iOS 18.5
集成image_picker
在Flutter中可以使用image_picker
插件實現從相冊中獲取圖片
添加插件
flutter中訪問相冊image_picker
插件
¥ flutter pub add image_picker
¥ flutter pub get
Xcode工程的GeneratePluginRegistrant新增了對應的注冊代碼
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
...[FLTImagePickerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTImagePickerPlugin"]];
...
}
更新Xcode的pod依賴
¥ pod update

添加權限
<key>NSPhotoLibraryUsageDescription</key>
<string>需要訪問相冊以選擇圖片</string><!-- image_picker也支持直接拍照 -->
<key>NSCameraUsageDescription</key>
<string>需要訪問相機用于拍照</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要訪問麥克風用于拍攝視頻</string>
獲取單張照片
可以使用ImagePicker().pickerImage()
獲取單張圖片
else if (index == 2) {_pickImage(ImageSource.gallery),
}
Future<void> _pickImage(ImageSource source) async {try {// source值可以是相機(camera)或相冊(gallery)final pickedFile = await ImagePicker().pickImage(source: source);if (pickedFile != null) {setState(() {if (mounted) {// pop彈窗并返回從相冊中選擇的圖片Navigator.pop(context, pickedFile);}});}} catch (e) {debugPrint("圖片選擇錯誤: $e");}}
在上一個界面接收從相冊中選擇的圖片并刷新界面
floatingActionButton: FloatingActionButton(onPressed: () async {final result = await menuWidget(context: context);if (result != null) {setState(() {_defaultCover = result;});}},backgroundColor: Colors.orangeAccent,child: const Icon(Icons.add, color: Colors.white),
),Future menuWidget({required BuildContext context}) async {return Navigator.push(context,PageRouteBuilder(opaque: false,barrierColor: Colors.black.withValues(alpha: 0.2),pageBuilder:(context, animation, secondaryAnimation) =>PopScope(canPop: true, child: MenuWidget()),transitionsBuilder:(context, animation, secondaryAnimation, child) => SlideTransition(position: Tween<Offset>(begin: const Offset(0.0, 2.4),end: Offset.zero,).animate(animation),child: SlideTransition(position: Tween<Offset>(begin: Offset.zero,end: const Offset(0.0, 2.4),).animate(secondaryAnimation),child: child,),),),);
}
iOS

Andorid

獲取多張照片
可以使用ImagePicker().pickMultiImage()
獲取多張圖片
_pickMultiImage(),
Future<void> _pickMultiImage() async {try {// 設置最多獲取9張圖片final pickedFiles = await ImagePicker().pickMultiImage(limit: 9);if (pickedFiles.isNotEmpty) {setState(() {if (mounted) {Navigator.pop(context, pickedFiles);}});}} catch (e) {debugPrint("圖片選擇錯誤: $e");}
}
floatingActionButton: FloatingActionButton(onPressed: () async {final result = await menuWidget(context: context);if (result != null) {setState(() {if (result is XFile) {_defaultCover = result;/// 選擇多張照片} else if (result is List<XFile>) {_defaultCover = result[0];}});}},backgroundColor: Colors.orangeAccent,child: const Icon(Icons.add, color: Colors.white),),
選擇多張照片在iOS平臺上只在14+才生效,用的是PhotosUI.framework中的PHPicker,因為手上測試機是13.4.1設備一直無法多選圖片,查看源碼
- (void)pickMultiImageWithMaxSize:(nonnull FLTMaxSize *)maxSizequality:(nullable NSNumber *)imageQualityfullMetadata:(BOOL)fullMetadatalimit:(nullable NSNumber *)limitcompletion:(nonnull void (^)(NSArray<NSString *> *_Nullable,FlutterError *_Nullable))completion {[self cancelInProgressCall];FLTImagePickerMethodCallContext *context =[[FLTImagePickerMethodCallContext alloc] initWithResult:completion];context.maxSize = maxSize;context.imageQuality = imageQuality;context.requestFullMetadata = fullMetadata;context.maxImageCount = limit.intValue;if (@available(iOS 14, *)) {[self launchPHPickerWithContext:context];} else {// Camera is ignored for gallery mode, so the value here is arbitrary.[self launchUIImagePickerWithSource:[FLTSourceSpecification makeWithType:FLTSourceTypeGallerycamera:FLTSourceCameraRear]context:context];}
}

limit值傳了9,但是launchUIImagePickerWithSource:context:
中沒有對limit做任何處理代碼
- (void)launchUIImagePickerWithSource:(nonnull FLTSourceSpecification *)sourcecontext:(nonnull FLTImagePickerMethodCallContext *)context {UIImagePickerController *imagePickerController = [self createImagePickerController];imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;imagePickerController.delegate = self;...

獲取視頻
使用ImagePicker().pickMedia()
可以從相冊獲取視頻文件
Future<void> _pickVideo() async {try {final pickedVideo = await ImagePicker().pickMedia();if (pickedVideo != null) {setState(() {});}} catch (e) {debugPrint("圖片選擇錯誤: $e");}
}

獲取多媒體文件
使用ImagePicker().pickMultipleMedia()
可以從相冊獲取視頻和照片
Future<void> _pickMultiMedia() async {try {final pickedMedia = await ImagePicker().pickMultipleMedia();setState(() {// 頁面刷新Navigator.pop(context, pickedMedia);});} catch (e) {debugPrint("圖片選擇錯誤: $e");}
}
參考
- Image Picker plugin for Flutter