前言

iOS下类似的图片浏览器不管是OC版本还是Swift版本目前已经开源了不少。但是作为一个六七年的老iOS开发者,以及自己曾经积累了的不少社交App经验,还是忍不住基于自己的想法以及目前项目中类似的组件重新撸了一个。毫无疑问,此次开源的JFHeroBrowser,首选语言是Swift(完全Swift不包含任何OC代码),偏向更Swifty的方式-面向协议处理数据模型,还有Swift进阶枚举用法,命名空间等,如果你想深入学习Swift,我相信本组件会让你有不同的体验,另外由于楼主同时也在开发Flutter,编码方式上也是更"响应式"。而且与大多数三方库内置ImageCache(大多是SDWebImage)不同,本组件,不包含内置的ImageCache,但是如果您集成了本项目作为图片浏览,网络图这块,您需要自行实现HeroNetworkImageProvider协议,可以使用Kingfisher或SDWebImage抑或是你项目中自行设计的图片缓存,完美解决组件耦合问题,具体使用参考下面用法。另外本组件支持多种资源格式,如本地图(UIImage),网络图(url),data(二进制),视频(url),甚至你自行实现ImageVM也可以接入你想要的资源。话不多说,我们来看具体使用方式。

下载安装地址

cocoaPods:

pod 'JFHeroBrowser', '1.3.2'

github:

https://github.com/JerryFans/JFHeroBrowser

Usage

首先初始化配置

如上面所说,在Appdelegate didFinish处自行接入HeroNetworkImageProvider。实现func downloadImage(with imgUrl: String, complete: Complete?)

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {JFHeroBrowserGlobalConfig.default.networkImageProvider = HeroNetworkImageProvider.shared//        JFHeroBrowserGlobalConfig.default.networkImageProvider = SDWebImageNetworkImageProvider.sharedreturn true}

Kingfisher参考


extension HeroNetworkImageProvider: NetworkImageProvider {func downloadImage(with imgUrl: String, complete: Complete<UIImage>?) {KingfisherManager.shared.retrieveImage(with: URL(string: imgUrl)!, options: nil) { receiveSize, totalSize inguard totalSize > 0 else { return }let progress:CGFloat = CGFloat(CGFloat(receiveSize) / CGFloat(totalSize))complete?(.progress(progress))} downloadTaskUpdated: { task in} completionHandler: { result inswitch result {case .success(let loadingImageResult):complete?(.success(loadingImageResult.image))breakcase .failure(let error):complete?(.failed(error))break}}}
}class HeroNetworkImageProvider: NSObject {@objc static let shared = HeroNetworkImageProvider()
}

SDWebImage参考


extension SDWebImageNetworkImageProvider: NetworkImageProvider {func downloadImage(with imgUrl: String, complete: Complete<UIImage>?) {SDWebImageManager.shared.loadImage(with: URL(string: imgUrl)) { receiveSize, totalSize, url inguard totalSize > 0 else { return }let progress:CGFloat = CGFloat(CGFloat(receiveSize) / CGFloat(totalSize))complete?(.progress(progress))} completed: { image, data, error, _, isfinished, url inif let error = error {complete?(.failed(error))} else if let image = image {complete?(.success(image))} else {complete?(.failed(nil))}}}
}class SDWebImageNetworkImageProvider: NSObject {@objc static let shared = SDWebImageNetworkImageProvider()
}

然后定义你需要浏览的ViewModule

目前支持HeroBrowserNetworkImageViewModule、HeroBrowserDataImageViewModule、HeroBrowserLocalImageViewModule、HeroBrowserVideoViewModule四种类型ViewModule。理论上还可以定义AssetImageViewModule(支持从相册浏览图片),在我另外一个未开源的相册组件里面使用了,所以ViewModule的扩展非常方便使用者去扩展各种各样的场景,而且单一场景,由于某些特定场景比较不场景,我这只提供几种常用的场景。

几种ViewModule代码示例

//视频
let vm1 = HeroBrowserVideoViewModule(thumbailImgUrl: "http://image.jerryfans.com/bf.jpg", fileUrlPath: path, provider: HeroNetworkImageProvider.shared, autoPlay: false)list.append(vm1)//本地图(UIImage)list.append(HeroBrowserLocalImageViewModule(image: img))//data图 (file Image支持转二进制,或者flutter的Uin8List)list.append(HeroBrowserDataImageViewModule(data: imageSource[i]))//网络图 也是最常用场景list.append(HeroBrowserNetworkImageViewModule(thumbailImgUrl: thumbs[i], originImgUrl: origins[i]))

然后是具体使用示例

浏览图片

self是当前控制器,写了一个hero的命名空间,viewModules就是上面一个个定义的viewModule示例,支持视频或者不同图片VM混搭也是可以的。

另外支持参数:

  • pageControlType (默认pageControl或者数字1/5类似)
  • heroView (也就是你要放大缩放那个imageView,如果不填就不会有缩放的效果,就是一个alpha渐变)
  • heroBrowserDidLongPressHandle (长按回调,可以做些保存图片、分享等动作)
  • imageDidChangeHandle (切换图片后,上个页面的imageView也要切换,才可以dissmiss回到相应位置,如果不设置就是alpha效果)
  • enableBlurEffect 是否开启毛玻璃背景,默认开启,false就是黑色背景。
 self.hero.browserPhoto(viewModules: list, initIndex: indexPath.item) {[.pageControlType(.pageControl),.heroView(cell.imageView),.heroBrowserDidLongPressHandle({ [weak self] heroBrowser,vm  inself?.longPressHandle(vm: vm)}),.imageDidChangeHandle({ [weak self] imageIndex inguard let self = self else { return nil }guard let cell = self.collectionView.cellForItem(at: IndexPath(item: imageIndex, section: 0)) as? NetworkImageCollectionViewCell else { return nil }let rect = cell.convert(cell.imageView.frame, to: self.view)if self.view.frame.contains(rect) {return cell.imageView}return nil})]}
浏览单个视频

效果:


let vm = HeroBrowserVideoViewModule(thumbailImgUrl: "http://image.jerryfans.com/w_720_h_1280_d_41_89fd26217dc299a442363581deb75b90_iOS_0.jpg", videoUrl: "http://image.jerryfans.com/w_720_h_1280_d_41_2508b8aa06a2e30d2857f9bcbdfd1de0_iOS.mp4", provider: HeroNetworkImageProvider.shared, autoPlay: true)self.hero.browserVideo(viewModule: vm)
浏览混合资源(图片+视频,或多个视频)

lazy var list: [HeroBrowserViewModuleBaseProtocol] = {var list: [HeroBrowserViewModuleBaseProtocol] = []let vm = HeroBrowserVideoViewModule(thumbailImgUrl: "http://image.jerryfans.com/w_720_h_1280_d_41_89fd26217dc299a442363581deb75b90_iOS_0.jpg", videoUrl: "http://image.jerryfans.com/w_720_h_1280_d_41_2508b8aa06a2e30d2857f9bcbdfd1de0_iOS.mp4", provider: HeroNetworkImageProvider.shared, autoPlay: true)list.append(vm)list.append(HeroBrowserLocalImageViewModule(image: UIImage(named: "template-1")!))if let path = Bundle.main.path(forResource: "bf.MOV", ofType: nil) {let vm1 = HeroBrowserVideoViewModule(thumbailImgUrl: "http://image.jerryfans.com/bf.jpg", fileUrlPath: path, provider: HeroNetworkImageProvider.shared, autoPlay: false)list.append(vm1)}return list}()self.hero.browserMultiSoures(viewModules: self.list, initIndex: 1) {[.enableBlurEffect(false),.heroView(button.imageView),.imageDidChangeHandle({ [weak self] imageIndex inguard let self = self else { return nil }guard let btn = self.view.viewWithTag(imageIndex) as? UIButton else { return nil }return btn.imageView})]}

SwiftUI的支持

一开始的想法是通过官方的UIViewController转换成SwiftUI的写法,但实现中发现不少问题,特别是转场效果无从下手。如果要纯SwiftUI代码实现,看来只能使用SwiftUI布局的方式重写,期待之后有空可以做个尝试。但是实际上,HeroBrowser是通过modal的方式进场的,我们直接获取rootViewController直接跳转亦可,但是就是缺少缩放动画,使用了默认的alpha转场,代码如下。本demo也提交到github了,有需要可以查阅。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qMG2KusP-1658281692470)(http://image.jerryfans.com/swiftui_example.gif)]

配置初始化代码


class AppDelegate: NSObject, UIApplicationDelegate {func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {JFHeroBrowserGlobalConfig.default.networkImageProvider = HeroNetworkImageProvider.sharedreturn true}
}@main
struct SwiftUIExampleApp: App {@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegatevar body: some Scene {WindowGroup {ContentView()}}
}
//获取顶层vclet keyWindow = UIApplication.shared.connectedScenes.map({ $0 as? UIWindowScene }).compactMap({ $0 }).first?.windows.firstlet myAppRootVC : UIViewController? = keyWindow?.rootViewController//从一个图片 GridView 跳转浏览LazyVGrid(columns: columns) {ForEach(1..<origins.count, id:\.self) { index inImageCell(index: index).frame(height: columns.count == 1 ? 300 : 150).onTapGesture {var list: [HeroBrowserViewModule] = []for i in 0..<origins.count {list.append(HeroBrowserNetworkImageViewModule(thumbailImgUrl: thumbs[i], originImgUrl: origins[i]))}myAppRootVC?.hero.browserPhoto(viewModules: list, initIndex: index)}}}

附件地址

  • 项目GitHub地址: JFHeroBrowser
  • Example https://github.com/JerryFans/JFHeroBrowser/tree/master/Example
  • SwiftUIExample https://github.com/JerryFans/JFHeroBrowser/tree/master/SwiftUIExample

支持SwiftUI!Swift版图片视频浏览器-JFHeroBrowser上线啦相关推荐

  1. HTML5 浏览器支持(怎么样让低版本浏览器支持html5?)

    你可以让一些较早的浏览器(不支持HTML5)支持 HTML5. 现代的浏览器都支持 HTML5. 此外,所有浏览器,包括旧的和最新的,对无法识别的元素会作为内联元素自动处理. 正因为如此,你可以 &q ...

  2. java做flv直播服务器,EasyDSS流媒体服务器软件(支持RTMP/HLS/HTTP-FLV/视频点播/视频直播)-正式环境安装部署攻略...

    EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作. 其中,点播功能主要包含:上传.转码.分发.直播功能,主要包含:直播.录像, 直播支持RTMP ...

  3. linux多点触摸屏驱动程序,Linux系统实现支持多点触控操作[视频]

    虽然大多数人目前还不会购买拥有触控屏的设备,不过在Windows 7的大力推动下,触控操作已经开始流行了起来.然而Linux目前却无法支持这一功能,这让很多用户十分郁闷,不过来自ENAC Intera ...

  4. 永恒之塔linux服务端,【永恒之塔单机5.8-6.5服务端】2020.06首发一键安装PC大型端游单机游戏客户端支持局域网联机玩[附视频搭建教程]...

    [永恒之塔单机5.8-6.5服务端]2020.06首发一键安装PC大型端游单机游戏客户端支持局域网联机玩[附视频搭建教程] 01.支持全新机甲星技能.羽毛觉醒.GP点.觉醒水 02.优化怪物掉落数据, ...

  5. 互联网晚报 | 1月8日 星期六 | 小米商城已支持数字人民币支付;微信视频号将上线付费直播间;苹果CEO去年薪酬近1亿美元...

    今日看点 ✦ 微信直播即将上线知识专栏,微信视频号即将上线付费直播间 ✦ 淘宝直播启动"发光俱乐部"计划,为商家和主播提供全面立体扶持 ✦ 天星数科携手小米商城上线数字人民币支付服 ...

  6. 苹果CMSv10首款原创支持百度mip技术自适应视频模板

    苹果CMSv10首款原创支持百度mip技术自适应视频模板 苹果cms10好看的模板自适应_苹果cmsv10高端模板_苹果cmsv10简洁模板 首款支持DIY的宽屏模板,彰显大气风格,完美自适应支持手机 ...

  7. macOS SwiftUI 教程之仿Safari浏览器地址栏(教程含源码)

    实战需求 macOS SwiftUI 教程之仿Safari浏览器地址栏 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 工具栏 .toolbar 搜索框 TextField ...

  8. S60V5版本的手机QQ支持截图、语音和视频功能

    S60V5版本的手机QQ支持截图.语音和视频功能吗? 一.截图功能: 目前最新版本支持截图功能,请您登录手机QQ=>点击右下角个人头像=>设置管理=>开启"长按拍照键开启截 ...

  9. 苹果CMSv10首涂第十六套首款原创支持百度mip技术自适应视频模板

    苹果CMSv10首涂第十六套首款原创支持百度mip技术自适应视频模板 首涂[第十六套]苹果CMSv10首款原创支持百度mip技术自适应视频模板 首款支持mip加速技术的模板,样式简洁速度快采用最新百度 ...

  10. TYPE-C桌面显示器专业解决方案( LDR6290 支持100W反向供电和视频传输)

    单USB Type-C接口,同时具有HDMI/USB扩展和直流供电,桌面式显示器的典型形态,整个显示器通过DC接口输入类似24V/3A的大功率电源,出了满足本身的功率需求,还可以为通过USB Type ...

最新文章

  1. 一年月份大小月口诀_有关12个月份的顺口溜
  2. oracle 的替代变量和
  3. 1.2.1 分层结构 协议 接口 服务
  4. Yum在线升级之网络(本地)服务器的搭建!
  5. 关于《计算机程序的构造和解释》
  6. CCNA1 - Final Exam Answers (04/18/2008 10:30)
  7. webpack简单修改版本号(单页面)
  8. python 文件和目录 当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径。
  9. mcq 队列_人工智能能力问答中的人工智能概率推理(MCQ)
  10. Arduino+Avr libc制作Badusb原理及示例讲解
  11. js中对于json判断的总结(持续整理中~)
  12. shop++源码反编译----随笔
  13. 轴系ansys命令流建模
  14. 合作开发过程产生的专利_合作开发合同和技术联营合同的区别及
  15. note同步不及时 one_解决无法同步 OneNote 的问题
  16. 超市销售数据分析python_python实战案例:超市营业额数据分析
  17. 数据挖掘:实用案例分析 下载_真经阁丨萌低龄,超实用“萌系”呈现技巧及设计案例分析...
  18. unity3d绘画手册-------地形高度调节
  19. 总结非结构化数据分析「十步走」
  20. 【Vue.js 3.0源码】KeepAlive 组件:如何让组件在内存中缓存和调度?

热门文章

  1. matlab符号表达式vpa,Matlab符号运算总结
  2. iOS category内部实现原理
  3. 什么是搜索引擎关键词?搜索引擎关键词优化
  4. Unison 的相关参数介绍
  5. 贪吃蛇源码(C语言版)-学习版
  6. Windows Message ID
  7. C语言|计算流逝后的时间
  8. html id 重复,Apple ID一直重复登录无效!怎么处理!
  9. 15亿美元买个“便宜货”
  10. 不定时更新-JAVA干货博客