You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 11截图标记功能编程调用:如何在程序截图后触发标记选项?

解决iOS代码截图后唤起标记/分享选项的问题

嘿,这个问题我之前做项目的时候也踩过坑!你手动截图后看到的那个标记/分享界面,其实是iOS系统自带的UIActivityViewController结合编辑功能实现的,而你之前的代码直接把截图静默保存到相册,自然不会弹出这个界面啦。下面给你两种可行的解决方案:

方案一:和手动截图体验完全一致(推荐)

直接用系统的UIActivityViewController来唤起标记界面,用户编辑完还能选择保存到相册、分享到其他APP,和手动截图的流程一模一样。修改你的代码如下:

@IBAction func takeScreenshot(_ sender: Any) { 
    // 生成截图的逻辑保持不变
    guard let keyWindow = UIApplication.shared.keyWindow else { return }
    let layer = keyWindow.layer 
    let scale = UIScreen.main.scale 
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale); 
    layer.render(in: UIGraphicsGetCurrentContext()!) 
    let screenshot = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    // 替换原来的保存代码,改用系统活动视图控制器
    guard let image = screenshot else { return }
    let activityVC = UIActivityViewController(activityItems: [image], applicationActivities: nil)
    // 开启编辑功能,这一步是唤起标记界面的关键
    activityVC.allowsEditing = true
    
    // iPad适配:必须设置popover的来源,否则会崩溃
    if let popoverController = activityVC.popoverPresentationController {
        if let button = sender as? UIButton {
            popoverController.sourceView = button
            popoverController.sourceRect = button.bounds
        } else {
            popoverController.sourceView = view
            popoverController.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
        }
    }
    
    present(activityVC, animated: true, completion: nil)
}

方案二:仅唤起标记界面,编辑后自动保存到相册

如果你只需要让用户标记图片,然后自动保存到相册(不需要分享选项),可以先把截图存到临时目录,再用UIImagePickerController打开编辑界面,编辑完成后保存到相册。代码示例如下:

@IBAction func takeScreenshot(_ sender: Any) { 
    // 生成截图逻辑不变
    guard let keyWindow = UIApplication.shared.keyWindow else { return }
    let layer = keyWindow.layer 
    let scale = UIScreen.main.scale 
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale); 
    layer.render(in: UIGraphicsGetCurrentContext()!) 
    let screenshot = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    guard let image = screenshot else { return }
    
    // 保存截图到临时目录
    let tempDir = NSTemporaryDirectory()
    let tempPath = tempDir.appending("screenshot_temp.png")
    guard let data = image.pngData() else { return }
    try? data.write(to: URL(fileURLWithPath: tempPath))
    
    // 初始化图片选择器,开启编辑模式
    let imagePicker = UIImagePickerController()
    imagePicker.sourceType = .photoLibrary
    imagePicker.mediaTypes = [kUTTypeImage as String]
    imagePicker.allowsEditing = true
    imagePicker.delegate = self
    
    present(imagePicker, animated: true)
}

// 实现UIImagePickerControllerDelegate协议
extension YourViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true) {
            // 获取编辑后的图片
            guard let editedImage = info[.editedImage] as? UIImage else { return }
            // 保存到相册
            UIImageWriteToSavedPhotosAlbum(editedImage, self, #selector(self.imageSaved(_:didFinishSavingWithError:contextInfo:)), nil)
        }
    }
    
    @objc func imageSaved(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
        if let error = error {
            print("保存失败:\(error.localizedDescription)")
        } else {
            print("图片已保存到相册")
        }
    }
}

注意事项

  • 方案一中的iPad适配非常重要,如果不设置popoverPresentationController的来源,iPad上会直接崩溃。
  • 确保你的视图控制器有权限弹出模态视图(比如当前控制器是导航栈的一部分,或者是根控制器)。
  • 方案二需要在Info.plist中添加NSPhotoLibraryUsageDescription权限描述,否则会被系统拒绝。

内容的提问来源于stack exchange,提问作者johnny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:49:13