TZImagePickerController与Swift项目集成指南:从配置到高级功能全解析

TZImagePickerController与Swift项目集成指南:从配置到高级功能全解析

【免费下载链接】TZImagePickerController 一个支持多选、选原图和视频的图片选择器,同时有预览、裁剪功能,支持iOS6+。 A clone of UIImagePickerController, support picking multiple photos、original photo、video, also allow preview photo and video, support iOS6+ 【免费下载链接】TZImagePickerController 项目地址: https://gitcode.com/gh_mirrors/tz/TZImagePickerController

你是否还在为iOS项目中的图片选择功能开发而烦恼?既要支持多选、原图、视频,又要实现预览和裁剪,原生UIImagePickerController根本满足不了需求?本文将带你一步到位解决这些问题,通过详细的代码示例和配置说明,让你在Swift项目中轻松集成TZImagePickerController这个强大的图片选择框架。读完本文,你将掌握从基础配置、权限处理到高级定制的全流程,彻底解决图片选择功能开发的痛点。

一、框架简介与核心优势

TZImagePickerController是一个功能强大的图片选择框架(Image Picker Controller),作为原生UIImagePickerController的替代品,它提供了更丰富的功能和更灵活的定制选项。该框架支持多选图片、选择原图、视频选择,同时包含预览、裁剪等功能,最低支持iOS 10+系统。

1.1 核心功能对比

功能原生UIImagePickerControllerTZImagePickerController
多选图片❌ 不支持✅ 支持,可自定义最大选择数量
原图选择❌ 不支持✅ 支持,可控制是否显示原图选项
视频选择⚠️ 有限支持✅ 完整支持,可选择多个视频
预览功能⚠️ 基础支持✅ 高级预览,支持缩放、滑动切换
图片裁剪⚠️ 基础支持✅ 支持矩形和圆形裁剪,自定义尺寸
GIF支持❌ 不支持✅ 完整支持GIF预览和选择
自定义UI⚠️ 有限支持✅ 全面支持,可自定义几乎所有UI元素

1.2 框架结构概览

TZImagePickerController的核心结构包含以下几个主要部分:

mermaid

二、环境配置与集成步骤

2.1 系统要求与依赖

  • 最低系统版本:iOS 10.0+
  • 开发环境:Xcode 10.0+
  • 依赖框架:Photos.framework、PhotosUI.framework

2.2 集成方式选择

TZImagePickerController提供了多种集成方式,可根据项目需求选择最合适的方式:

2.2.1 CocoaPods集成(推荐)

在Podfile中添加以下代码:

# 完整版本,包含所有功能
pod 'TZImagePickerController'

# 基础版本,不包含定位相关代码
# pod 'TZImagePickerController/Basic'

执行以下命令安装:

pod install
2.2.2 手动集成
  1. 从Git仓库克隆或下载源代码:
git clone https://gitcode.com/gh_mirrors/tz/TZImagePickerController.git
  1. 将TZImagePickerController文件夹拖拽到Xcode项目中,确保勾选"Copy items if needed"和对应的target。

  2. 在项目设置中,确保以下框架已添加到"Link Binary With Libraries":

    • Photos.framework
    • PhotosUI.framework

2.3 Info.plist配置

TZImagePickerController需要访问相册、相机、麦克风和位置等权限,需在Info.plist中添加以下配置:

<key>NSCameraUsageDescription</key>
<string>需要访问相机以拍摄照片和视频</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择照片和视频</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要访问麦克风以录制视频</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要访问位置以记录照片位置信息</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问相册以保存照片和视频</string>
<key>Prevent limited photos access alert</key>
<true/>

三、Swift项目集成实战

3.1 桥接文件配置

由于TZImagePickerController是用Objective-C编写的,在Swift项目中使用需要创建桥接文件(Bridging Header):

  1. 创建一个新的头文件,命名为YourProjectName-Bridging-Header.h
  2. 在项目Build Settings中,找到"Objective-C Bridging Header"设置,填入桥接文件路径
  3. 在桥接文件中添加以下导入:
#import "TZImagePickerController.h"
#import "TZImageManager.h"
#import "TZAssetModel.h"

3.2 基础使用示例

以下是一个基本的Swift集成示例,展示如何在Swift项目中调用TZImagePickerController:

import UIKit
import Photos

class ViewController: UIViewController, TZImagePickerControllerDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        view.backgroundColor = .white
        
        let pickButton = UIButton(type: .system)
        pickButton.setTitle("选择图片", for: .normal)
        pickButton.addTarget(self, action: #selector(pickImageTapped), for: .touchUpInside)
        pickButton.frame = CGRect(x: 100, y: 200, width: 200, height: 50)
        view.addSubview(pickButton)
    }
    
    @objc private func pickImageTapped() {
        // 创建图片选择器实例
        let imagePicker = TZImagePickerController(maxImagesCount: 9, delegate: self)
        
        // 设置选择器属性
        imagePicker?.allowPickingOriginalPhoto = true
        imagePicker?.allowPickingVideo = true
        imagePicker?.allowPickingGif = true
        
        // 设置完成回调
        imagePicker?.setDidFinishPickingPhotosHandle({ (photos, assets, isSelectOriginal) in
            // 处理选择的图片
            print("选中了\(photos?.count ?? 0)张图片")
            print("是否选择原图: \(isSelectOriginal)")
            
            // 显示选中的图片
            self.showSelectedImages(photos: photos)
        })
        
        //  present选择器
        if let picker = imagePicker {
            present(picker, animated: true, completion: nil)
        }
    }
    
    private func showSelectedImages(photos: [UIImage]?) {
        // 实现显示选中图片的逻辑
        guard let photos = photos else { return }
        
        for (index, photo) in photos.enumerated() {
            let imageView = UIImageView(image: photo)
            imageView.frame = CGRect(x: 20 + (index % 3) * 100, 
                                    y: 300 + (index / 3) * 100, 
                                    width: 90, height: 90)
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
            view.addSubview(imageView)
        }
    }
}

3.3 代理方法实现

除了使用block回调,还可以通过实现代理方法来处理选择结果:

// MARK: - TZImagePickerControllerDelegate
extension ViewController {
    func imagePickerController(_ picker: TZImagePickerController!, didFinishPickingPhotos photos: [UIImage]!, sourceAssets assets: [Any]!, isSelectOriginalPhoto: Bool) {
        print("代理方法:选中了\(photos.count)张图片")
        showSelectedImages(photos: photos)
    }
    
    func imagePickerControllerDidCancel(_ picker: TZImagePickerController!) {
        print("用户取消了选择")
    }
    
    func imagePickerController(_ picker: TZImagePickerController!, didFinishPickingVideo coverImage: UIImage!, sourceAssets asset: PHAsset!) {
        print("选中了视频,时长:\(asset.duration)秒")
        let imageView = UIImageView(image: coverImage)
        imageView.frame = CGRect(x: 20, y: 300, width: 150, height: 150)
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        view.addSubview(imageView)
    }
}

四、高级功能与定制

4.1 自定义选择器属性

TZImagePickerController提供了丰富的属性来自定义其行为:

// 创建选择器实例
let imagePicker = TZImagePickerController(maxImagesCount: 5, delegate: self)

// 基本设置
imagePicker?.columnNumber = 4 // 每行显示4列
imagePicker?.allowTakePicture = true // 允许拍照
imagePicker?.allowTakeVideo = true // 允许拍摄视频
imagePicker?.videoMaximumDuration = 15 // 视频最大拍摄时长15秒
imagePicker?.sortAscendingByModificationDate = false // 按修改时间降序排列

// 选择限制
imagePicker?.minPhotoWidthSelectable = 800 // 最小可选图片宽度
imagePicker?.minPhotoHeightSelectable = 600 // 最小可选图片高度

// 外观设置
imagePicker?.naviBgColor = .darkGray // 导航栏背景色
imagePicker?.naviTitleColor = .white // 导航栏标题颜色
imagePicker?.oKButtonTitleColorNormal = .systemBlue // 确认按钮颜色
imagePicker?.iconThemeColor = .systemGreen // 选中图标主题色

// 预览设置
imagePicker?.allowPreview = true // 允许预览
imagePicker?.photoPreviewMaxWidth = 1000 // 预览图片最大宽度

// 裁剪设置(单选模式下)
imagePicker?.allowCrop = true // 允许裁剪
imagePicker?.needCircleCrop = false // 不需要圆形裁剪
imagePicker?.cropRect = CGRect(x: 50, y: 200, width: 300, height: 300) // 裁剪框大小

4.2 单选与裁剪功能

设置单选模式并启用裁剪功能:

func showSingleImagePickerWithCrop() {
    // 创建单选模式的图片选择器
    let imagePicker = TZImagePickerController(maxImagesCount: 1, delegate: self)
    
    // 启用裁剪功能
    imagePicker?.allowCrop = true
    imagePicker?.showSelectBtn = false // 隐藏选择按钮
    
    // 设置裁剪参数
    imagePicker?.needCircleCrop = false // 矩形裁剪
    // 如果需要圆形裁剪,设置为true并指定半径
    // imagePicker?.needCircleCrop = true
    // imagePicker?.circleCropRadius = 100
    
    // 设置裁剪框大小(竖屏)
    let screenWidth = UIScreen.main.bounds.width
    let cropWidth: CGFloat = screenWidth - 100
    let cropRect = CGRect(x: 50, 
                         y: (UIScreen.main.bounds.height - cropWidth) / 2, 
                         width: cropWidth, 
                         height: cropWidth)
    imagePicker?.cropRect = cropRect
    
    // 设置完成回调
    imagePicker?.setDidFinishPickingPhotosHandle({ (photos, assets, isSelectOriginal) in
        if let croppedImage = photos?.first {
            // 显示裁剪后的图片
            let imageView = UIImageView(image: croppedImage)
            imageView.frame = CGRect(x: 50, y: 200, width: 200, height: 200)
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
            self.view.addSubview(imageView)
        }
    })
    
    if let picker = imagePicker {
        present(picker, animated: true, completion: nil)
    }
}

4.3 视频选择与编辑

配置视频选择和编辑功能:

func showVideoPicker() {
    let imagePicker = TZImagePickerController(maxImagesCount: 1, delegate: self)
    
    // 配置视频选择
    imagePicker?.allowPickingVideo = true // 允许选择视频
    imagePicker?.allowPickingImage = false // 不允许选择图片
    imagePicker?.allowEditVideo = true // 允许编辑视频
    imagePicker?.videoMaximumDuration = 30 // 最大视频时长30秒
    
    // 设置视频编辑参数
    imagePicker?.maxCropVideoDuration = 15 // 裁剪视频最大时长15秒
    imagePicker?.presetName = AVAssetExportPresetMediumQuality // 导出质量
    
    // 设置视频选择回调
    imagePicker?.setDidFinishPickingPhotosHandle({ (photos, assets, isSelectOriginal) in
        // 视频封面图在photos数组中
        if let coverImage = photos?.first {
            print("视频封面图获取成功")
            // 显示封面图
            let imageView = UIImageView(image: coverImage)
            imageView.frame = CGRect(x: 50, y: 200, width: 200, height: 150)
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
            self.view.addSubview(imageView)
        }
        
        // 视频资源在assets数组中
        if let asset = assets?.first as? PHAsset {
            print("选中视频时长: \(asset.duration)秒")
            
            // 获取视频URL
            TZImageManager.manager().getVideoWithAsset(asset, completion: { (videoUrl, error) in
                if let url = videoUrl {
                    print("视频URL: \(url)")
                    // 在这里可以播放视频或上传
                }
            })
        }
    })
    
    if let picker = imagePicker {
        present(picker, animated: true, completion: nil)
    }
}

4.4 UI定制

自定义导航栏和底部工具栏样式:

func customizeImagePickerUI() {
    let imagePicker = TZImagePickerController(maxImagesCount: 9, delegate: self)
    
    // 自定义导航栏
    imagePicker?.naviBgColor = .white
    imagePicker?.naviTitleColor = .black
    imagePicker?.naviTitleFont = UIFont.boldSystemFont(ofSize: 18)
    
    // 自定义按钮文字
    imagePicker?.doneBtnTitleStr = "完成"
    imagePicker?.cancelBtnTitleStr = "取消"
    imagePicker?.previewBtnTitleStr = "预览"
    
    // 自定义按钮颜色
    imagePicker?.oKButtonTitleColorNormal = .systemBlue
    imagePicker?.oKButtonTitleColorDisabled = .lightGray
    imagePicker?.barItemTextColor = .black
    
    // 自定义选中图标颜色
    imagePicker?.iconThemeColor = .systemRed
    
    // 自定义相册列表页UI
    imagePicker?.albumPickerPageUIConfigBlock = { tableView in
        tableView.backgroundColor = .systemBackground
        tableView.separatorColor = .systemGray5
    }
    
    // 自定义照片选择页UI
    imagePicker?.photoPickerPageUIConfigBlock = { collectionView, toolBar, previewBtn, originalBtn, originalLabel, doneBtn, numberImgView, numberLabel, divideLine in
        // 自定义底部工具栏
        toolBar.backgroundColor = .white
        
        // 自定义预览按钮
        previewBtn.setTitleColor(.systemBlue, for: .normal)
        previewBtn.setTitleColor(.lightGray, for: .disabled)
        
        // 自定义原图按钮
        originalBtn.tintColor = .systemBlue
        
        // 自定义完成按钮
        doneBtn.backgroundColor = .systemBlue
        doneBtn.layer.cornerRadius = 22
        doneBtn.clipsToBounds = true
    }
    
    if let picker = imagePicker {
        present(picker, animated: true, completion: nil)
    }
}

五、常见问题与解决方案

5.1 权限处理

在使用TZImagePickerController之前,最好先检查并请求必要的权限:

import Photos

func checkPhotoPermissions(completion: @escaping (Bool) -> Void) {
    let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
    
    switch status {
    case .authorized:
        completion(true)
    case .denied, .restricted:
        // 权限被拒绝,提示用户去设置中开启
        showPermissionDeniedAlert()
        completion(false)
    case .notDetermined:
        // 请求权限
        PHPhotoLibrary.requestAuthorization(for: .readWrite) { newStatus in
            DispatchQueue.main.async {
                if newStatus == .authorized {
                    completion(true)
                } else {
                    self.showPermissionDeniedAlert()
                    completion(false)
                }
            }
        }
    case .limited:
        // iOS 14+ 有限权限
        completion(true)
    @unknown default:
        completion(false)
    }
}

func showPermissionDeniedAlert() {
    let alert = UIAlertController(title: "无法访问相册", 
                                 message: "请在设置中允许应用访问相册", 
                                 preferredStyle: .alert)
    
    alert.addAction(UIAlertAction(title: "取消", style: .cancel))
    alert.addAction(UIAlertAction(title: "设置", style: .default) { _ in
        if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
            UIApplication.shared.open(settingsURL)
        }
    })
    
    present(alert, animated: true)
}

// 使用示例
func pickImageWithPermissionCheck() {
    checkPhotoPermissions { granted in
        if granted {
            // 权限已授予,显示图片选择器
            self.showImagePicker()
        }
    }
}

5.2 性能优化

处理大量图片时的性能优化建议:

// 1. 控制图片尺寸,避免加载过大图片
let imagePicker = TZImagePickerController(maxImagesCount: 9, delegate: self)
imagePicker?.photoWidth = 800 // 控制输出图片宽度为800px
imagePicker?.photoPreviewMaxWidth = 1000 // 控制预览图片宽度

// 2. 使用NSOperationQueue控制并发数
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 3 // 限制最大并发数为3

// 3. 获取原图时使用异步方式
func getOriginalImage(for asset: PHAsset, completion: @escaping (UIImage?) -> Void) {
    let options = PHImageRequestOptions()
    options.isSynchronous = false
    options.deliveryMode = .highQualityFormat
    options.resizeMode = .none
    options.isNetworkAccessAllowed = true // 允许从iCloud下载
    
    let manager = PHImageManager.default()
    let targetSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
    
    manager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: options) { image, info in
        DispatchQueue.main.async {
            completion(image)
        }
    }
}

// 4. 处理iCloud图片时显示进度提示
func handleICloudAsset(asset: PHAsset) {
    let options = PHImageRequestOptions()
    options.isNetworkAccessAllowed = true
    options.progressHandler = { progress, error, stop, info in
        DispatchQueue.main.async {
            let progressValue = Float(progress)
            // 更新进度指示器
            print("加载进度: \(progressValue * 100)%")
        }
    }
    
    TZImageManager.manager().getPhotoWithAsset(asset, options: options, completion: { image, info, isDegraded in
        if let image = image {
            print("图片加载完成")
            // 显示图片
        }
        
        if let info = info, let isCloud = info[PHImageResultIsInCloudKey] as? Bool, isCloud {
            if let error = info[PHImageErrorKey] as? NSError {
                print("iCloud图片加载失败: \(error.localizedDescription)")
            }
        }
    })
}

5.3 多语言支持

TZImagePickerController内置了多语言支持,可通过以下方式设置:

// 在初始化图片选择器前设置首选语言
let config = TZImagePickerConfig.sharedInstance()
config.preferredLanguage = "zh-Hans" // 简体中文
// config.preferredLanguage = "en" // 英文
// config.preferredLanguage = "ja" // 日文
// config.preferredLanguage = "ko-KP" // 韩文
// config.preferredLanguage = "vi" // 越南语

// 或者直接设置语言bundle
if let bundlePath = Bundle.main.path(forResource: "zh-Hant", ofType: "lproj") {
    let languageBundle = Bundle(path: bundlePath)
    config.languageBundle = languageBundle
}

// 然后再创建图片选择器
let imagePicker = TZImagePickerController(maxImagesCount: 9, delegate: self)

六、最佳实践与性能优化

6.1 内存管理

图片选择过程中的内存管理最佳实践:

// 1. 使用弱引用避免循环引用
func showImagePicker() {
    let imagePicker = TZImagePickerController(maxImagesCount: 9, delegate: self)
    imagePicker?.setDidFinishPickingPhotosHandle({ [weak self] photos, assets, isSelectOriginal in
        guard let self = self else { return }
        self.processSelectedImages(photos: photos, assets: assets)
    })
    present(imagePicker!, animated: true, completion: nil)
}

// 2. 及时释放大图资源
func processSelectedImages(photos: [UIImage]?, assets: [Any]?) {
    // 处理完成后立即释放内存
    DispatchQueue.global().async {
        autoreleasepool {
            // 处理图片的代码
            if let photos = photos {
                for image in photos {
                    // 处理每张图片
                }
            }
            
            // 处理完成后回到主线程更新UI
            DispatchQueue.main.async {
                // 更新UI
            }
        }
    }
}

// 3. 避免缓存过多图片
let imageCache = NSCache<NSString, UIImage>()

func cacheImage(image: UIImage, key: String) {
    // 设置缓存大小限制
    imageCache.totalCostLimit = 10 * 1024 * 1024 // 10MB
    imageCache.setObject(image, forKey: key as NSString)
}

// 4. 在适当的时候清理缓存
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    imageCache.removeAllObjects()
}

6.2 常见错误处理

处理图片选择过程中可能出现的错误:

// 1. 处理图片加载错误
func handleImageLoadingError(error: Error?, asset: PHAsset) {
    if let error = error as NSError? {
        switch error.code {
        case PHError.cancelled.rawValue:
            print("用户取消了图片加载")
        case PHError.imageDataUnavailable.rawValue:
            print("图片数据不可用")
            showErrorAlert(message: "无法加载图片数据")
        case PHError.cloudPhotoLibraryUnavailable.rawValue:
            print("iCloud照片库不可用")
            showErrorAlert(message: "iCloud照片库不可用,请检查网络连接")
        case PHError.networkAccessRequired.rawValue:
            print("需要网络连接")
            showErrorAlert(message: "需要网络连接才能加载此图片")
        default:
            print("图片加载错误: \(error.localizedDescription)")
            showErrorAlert(message: "图片加载失败: \(error.localizedDescription)")
        }
    }
}

// 2. 显示错误提示
func showErrorAlert(message: String) {
    let alert = UIAlertController(title: "错误", message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "确定", style: .default))
    present(alert, animated: true)
}

// 3. 处理视频导出错误
func imagePickerController(_ picker: TZImagePickerController!, didFailToSaveEditedVideoWithError error: Error!) {
    print("视频保存失败: \(error.localizedDescription)")
    showErrorAlert(message: "视频保存失败: \(error.localizedDescription)")
}

七、总结与展望

TZImagePickerController作为一个功能强大的图片选择框架,为iOS开发者提供了丰富的图片和视频选择功能。通过本文的介绍,你已经了解了如何在Swift项目中集成和使用这个框架,包括基础配置、权限处理、功能定制以及性能优化等方面。

7.1 核心功能回顾

  • 多选择功能:支持同时选择多张图片和视频
  • 原图选择:允许用户选择是否发送原图
  • 预览功能:提供图片和视频的预览能力
  • 裁剪功能:支持矩形和圆形裁剪,自定义尺寸
  • GIF支持:完整支持GIF图片的预览和选择
  • 视频编辑:支持视频裁剪和编辑
  • UI定制:几乎所有UI元素都可自定义

7.2 未来发展建议

随着iOS系统的不断更新,TZImagePickerController也在持续进化。未来使用中可以关注以下方向:

  1. Swift重构:虽然目前是Objective-C实现,但可以期待未来的Swift版本
  2. SwiftUI支持:随着SwiftUI的普及,框架可能会提供SwiftUI接口
  3. 性能优化:进一步优化大图片处理和iCloud图片加载性能
  4. AI功能集成:可能会集成图片识别、智能裁剪等AI功能

TZImagePickerController作为一个活跃的开源项目,持续接受社区贡献和改进。建议定期查看项目更新,以获取最新功能和bug修复。

通过合理利用TZImagePickerController,你可以为你的iOS应用快速添加专业级的图片选择功能,提升用户体验,同时减少开发工作量,将更多精力投入到应用的核心功能开发中。

【免费下载链接】TZImagePickerController 一个支持多选、选原图和视频的图片选择器,同时有预览、裁剪功能,支持iOS6+。 A clone of UIImagePickerController, support picking multiple photos、original photo、video, also allow preview photo and video, support iOS6+ 【免费下载链接】TZImagePickerController 项目地址: https://gitcode.com/gh_mirrors/tz/TZImagePickerController

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值