iOS Swift实现备忘录功能:将相册视频插入TextView
提问内容
我尝试过相关方法但均未成功,希望实现类似备忘录的功能:从相册选择视频并将其显示在TextView中。
我的代码如下:
extension DetailViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { videoURL = info[UIImagePickerController.InfoKey(rawValue: "UIImagePickerControllerReferenceURL") ] as? NSURL print(videoURL!) do { let asset = AVURLAsset(url: videoURL! as URL , options: nil) let imgGenerator = AVAssetImageGenerator(asset: asset) imgGenerator.appliesPreferredTrackTransform = true let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil) let thumbnail = UIImage(cgImage: cgImage) selectedImage = thumbnail } catch let error { print("*** Error generating thumbnail: \(error.localizedDescription)") } if var selectedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { let attachment = NSTextAttachment() if selectedImage.imageOrientation == .up || selectedImage.imageOrientation == .down { let img = selectedImage.resizeImage(image: selectedImage, targetSize: CGSize(width: self.view.frame.width - 50, height: self.view.frame.height)) attachment.image = img.imageWithSpacing(insets: UIEdgeInsets(top: 15, left: 0, bottom: 15, right: 0)) } else { let img = selectedImage.resizeImage(image: selectedImage, targetSize: CGSize(width: self.view.frame.width - 50, height: self.view.frame.height)) attachment.image = img.imageWithSpacing(insets: UIEdgeInsets(top: 15, left: 0, bottom: 15, right: 0)) } let attString = NSAttributedString(attachment: attachment) textView.textStorage.insert(attString, at: textView.selectedRange.location) picker.dismiss(animated: true, completion: nil) } let player = AVPlayer(url: videoURL! as URL) let playerController = AVPlayerViewController() playerController.player = player self.present(playerController, animated: true) { player.play() } let newPosition = textView.endOfDocument textView.selectedTextRange = textView.textRange(from: newPosition, to: newPosition) dismiss(animated: true, completion: nil) } }
我想了解如何将选中的视频正确插入TextView中,是否可以将videoURL转换为其他格式放入NSTextAttachment,或是该需求无法实现?
解决方案
TextView本身无法直接嵌入可播放的视频,但可以通过以下方式实现类似备忘录的效果:
1. 插入视频缩略图并绑定点击播放逻辑
NSTextAttachment仅支持承载图片,不能直接存储视频URL或文件。你可以用生成的视频缩略图作为附件插入TextView,再给缩略图添加点击手势触发播放:
核心修改步骤:
- 废弃原代码中依赖
info[.originalImage]的逻辑(视频选择时不会返回该值),直接用你生成的thumbnail创建NSTextAttachment - 自定义
NSTextAttachment子类,用来绑定对应的视频URL - 给TextView添加点击手势,判断点击位置是否为视频缩略图附件,触发播放
修改后的核心代码片段:
// 替换原代码中if var selectedImage = info[...]的部分 if let thumbnail = selectedImage { // 自定义附件类存储视频URL class VideoAttachment: NSTextAttachment { var videoURL: URL? } let videoAttachment = VideoAttachment() // 调整缩略图为16:9比例,适配TextView显示 let targetSize = CGSize(width: self.view.frame.width - 50, height: (self.view.frame.width - 50) * 9 / 16) let resizedImg = thumbnail.resizeImage(image: thumbnail, targetSize: targetSize) videoAttachment.image = resizedImg.imageWithSpacing(insets: UIEdgeInsets(top: 15, left: 0, bottom: 15, right: 0)) videoAttachment.videoURL = videoURL as URL? let attString = NSAttributedString(attachment: videoAttachment) textView.textStorage.insert(attString, at: textView.selectedRange.location) picker.dismiss(animated: true, completion: nil) } // 在viewDidLoad中添加TextView点击手势 override func viewDidLoad() { super.viewDidLoad() let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTextViewTap(_:))) textView.addGestureRecognizer(tapGesture) } // 点击处理方法 @objc func handleTextViewTap(_ gesture: UITapGestureRecognizer) { let location = gesture.location(in: textView) guard let position = textView.closestPosition(to: location), let attachment = textView.textStyling(at: position, in: .forward)?.attachment as? VideoAttachment, let url = attachment.videoURL else { return } // 播放视频 let player = AVPlayer(url: url) let playerController = AVPlayerViewController() playerController.player = player present(playerController, animated: true) { player.play() } }
2. 额外优化点
- 原代码中
UIImagePickerControllerReferenceURL已废弃,建议改用UIImagePickerController.InfoKey.mediaURL获取视频本地URL - 可以给缩略图叠加播放图标,让用户明确这是可点击的视频元素
- 确保已在
Info.plist中添加相册访问权限申请(NSPhotoLibraryUsageDescription)
内容的提问来源于stack exchange,提问作者Note The
相关产品推荐
相关产品推荐

