UIImagePickerController videoMaximumDuration失效及视频界面操作异常问题
Hey there! Let's tackle the two issues you're running into with UIImagePickerController and video handling—button unresponsiveness after showing an alert, and the videoMaximumDuration setting not working as expected. Here's a breakdown of what's going wrong and how to fix it:
Why this happens
When you detect a video longer than 15 seconds in didFinishPickingMediaWithInfo, you're trying to keep the UIImagePickerController open while showing an alert. But here's the catch: once the user taps "Use Video", the picker is already in the process of dismissing itself. Forcing it to stay open while presenting an alert messes up its internal interaction state, leading to those unclickable buttons.
The fix
Instead of keeping the picker open, first dismiss it properly, then show your alert from your main view controller. This way, you don't interfere with the picker's lifecycle, and your alert behaves as expected.
Here's the updated code for your delegate method:
import AVFoundation // Don't forget to import this for video duration checks func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { guard let videoURL = info[.mediaURL] as? URL else { picker.dismiss(animated: true) return } // Calculate video duration let asset = AVURLAsset(url: videoURL) let durationSeconds = CMTimeGetSeconds(asset.duration) if durationSeconds < 15.0 { // Duration is valid: dismiss picker and process the video picker.dismiss(animated: true) { [weak self] in self?.processSelectedVideo(url: videoURL) } } else { // Duration is too long: dismiss picker first, then show alert picker.dismiss(animated: true) { [weak self] in let alert = UIAlertController(title: "Video Too Long", message: "Your video exceeds 15 seconds. Would you like to crop it?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) alert.addAction(UIAlertAction(title: "Crop Video", style: .default) { _ in // Navigate to your custom video cropping screen here self?.presentVideoCropper(with: videoURL) }) self?.present(alert, animated: true) } } }
videoMaximumDuration Work Why it's not working
Chances are you're either setting the property in the wrong order, missing a critical configuration step, or haven't properly requested permissions. The videoMaximumDuration only applies when:
- The picker's
sourceTypeis set to.camera - You've specified the media type as video (not just images)
- You set the property before presenting the picker
- You have camera and microphone permissions granted
The fix
Update your picker setup code to follow this order and include all required configurations:
import MobileCoreServices // For kUTTypeMovie func openVideoCamera() { // First, check camera and microphone permissions checkPermissions { [weak self] granted in guard granted else { // Show alert asking user to enable permissions in Settings self?.showPermissionAlert() return } let picker = UIImagePickerController() picker.sourceType = .camera // Set media type to video first picker.mediaTypes = [kUTTypeMovie as String] // Set maximum duration to 15 seconds picker.videoMaximumDuration = 15.0 picker.delegate = self self?.present(picker, animated: true) } } // Helper method to check permissions private func checkPermissions(completion: @escaping (Bool) -> Void) { let cameraStatus = AVCaptureDevice.authorizationStatus(for: .video) let micStatus = AVCaptureDevice.authorizationStatus(for: .audio) var permissionsGranted = true if cameraStatus != .authorized { AVCaptureDevice.requestAccess(for: .video) { granted in permissionsGranted = granted } } if micStatus != .authorized { AVCaptureDevice.requestAccess(for: .audio) { granted in permissionsGranted = permissionsGranted && granted } } // If already authorized, call completion immediately if cameraStatus == .authorized && micStatus == .authorized { completion(true) } }
Key notes:
- Always set
mediaTypesbeforevideoMaximumDuration—the picker needs to know it's handling video first. - The
videoMaximumDurationwill automatically stop the camera once the 15-second mark is hit, preventing users from recording longer videos in the first place. - Permissions are non-negotiable: without camera and mic access, the picker won't function correctly, and duration limits won't apply.
内容的提问来源于stack exchange,提问作者Vinayak

