Coder Social home page Coder Social logo

jiongxing / photobrowser Goto Github PK

View Code? Open in Web Editor NEW
1.3K 16.0 207.0 28.99 MB

Elegant photo browser in Swift. 图片与视频浏览器。

License: MIT License

Swift 99.11% Ruby 0.89%
photo-browser transition-animation gesture image photo previewer browser swift

photobrowser's Introduction

JXPhotoBrowser

Version License Platform

(更多演示请看Demo)

特性

  • 支持图片、视频、图片与视频混合浏览
  • 支持横向和竖向滚动
  • 支持嵌入导航栏
  • 支持pushpresent打开
  • 支持数据源实时变更,框架不持有数据源
  • 支持自定义转场动画,框架提供了FadeZoomSoomthZoom三个转场动画的实现
  • 支持自定义Cell,框架提供了常用的图片展示Cell的实现
  • 支持网络图片加载、查看原图加载,由用户自由选择其他框架进行图片加载与缓存
  • 支持添加附加控件,框架提供了两种页面指示器的实现,以及在例子工程提供了加载进度环的实现

近期版本更新

Version 3.1.5

2024/02/05

  • 优化和修复已知问题,包括#213 #216 #217 #221 #224 #225

历史更新记录

环境要求

  • iOS 11.0 及以上

安装方法

Cocoapods

podfile配置

pod 'JXPhotoBrowser'

Swift Package Manager (Xcode 11+)

使用Xcode的包管理器添加本仓库URL。

File -> Swift Packages -> Add Package Dependency

添加URL:https://github.com/JiongXing/PhotoBrowser

Manual

把本仓库下载到你本地,然后把Sources文件夹下的JXPhotoBrowser文件夹整个拖入Xcode,勾选拷贝文件选项即可,没有其它第三方依赖。

使用方法

以下代码取自项目Example例子工程,更详细完整的代码请打开例子工程查看,下文是其关键代码的讲解。

基本用法

1.先实例化一个图片浏览器对象。

注意每次打开图片浏览,都应该重新实例化(重新实例化的开销很小,不必担心)。

let browser = JXPhotoBrowser()

2.实时提供图片总量。

因考虑到数据源有可能是在浏览过程中变化的,所以JXPhotoBrowser框架(以下简称'框架')将会在适当时机调用闭包动态获取当前用户的数据源数量,类似UITableView的机制。

browser.numberOfItems = {
    self.dataSource.count
}

3.刷新项视图。

框架的项视图(展示单张图片的View)是复用的,由最多3个视图重复使用来实现无限数量的图片浏览。

在每个项视图需要被刷新时,reloadCellAtIndex闭包将会被调用,用户应当在此时更新对应数据源的视图展示。

框架默认实现并使用了JXPhotoBrowserImageCell作为项视图,用户也可以自由定制项视图,更多细节在下文介绍。

JXPhotoBrowserImageCell有一个imageView视图,用户只需要对其加载图片即可正常使用。

browser.reloadCellAtIndex = { context in
    let browserCell = context.cell as? JXPhotoBrowserImageCell
    let indexPath = IndexPath(item: context.index, section: indexPath.section)
    browserCell?.imageView.image = self.dataSource[indexPath.item].localName.flatMap { UIImage(named: $0) }
}

4.指定打开图片浏览器时定位到哪一页。

所赋的值应当在用户数据源的范围内,如数据源共有10项,则pageIndex允许范围是0~9

browser.pageIndex = indexPath.item

5.显示图片浏览器

浏览器主类JXPhotoBrowser是一个UIViewController,支持导航栏push,也支持模态present。 框架提供的show()方法封装实现了常见的打开方式。

无参调用show()方法的时候,默认使用了present模态打开一个不带导航栏的图片浏览器。

browser.show()

转场动画

用户可自由编写自己的转场动画,也可以使用框架已实现的三种动画。 框架的转场动画实现类是一个遵循了JXPhotoBrowserAnimatedTransitioning协议的对象。只需要把动画实现类赋值给PhotoBrowsertransitionAnimator属性,即可生效。 如果用户不指定动画,transitionAnimator属性将会使用默认赋值的fade渐变动画。

lazy var transitionAnimator: JXPhotoBrowserAnimatedTransitioning = JXPhotoBrowserFadeAnimator()

框架实现了图片打开时从小图位置放大,关闭时缩小回原位置的动画效果(以下简称Zoom动画),有两种实现,分别是:JXPhotoBrowserZoomAnimatorJXPhotoBrowserSmoothZoomAnimator

JXPhotoBrowserZoomAnimator提供了最简便的方法让用户快速获得Zoom动画,只需要告诉框架,所浏览大图对应的缩略图视图即可。

browser.transitionAnimator = JXPhotoBrowserZoomAnimator(previousView: { index -> UIView? in
    let path = IndexPath(item: index, section: indexPath.section)
    let cell = collectionView.cellForItem(at: path) as? BaseCollectionViewCell
    return cell?.imageView
})

JXPhotoBrowserSmoothZoomAnimator提供了更丝滑流畅的Zoom动画,但是使用上会复杂一点,需要用户自己给出转场视图以及缩略图的位置大小。

browser.transitionAnimator = JXPhotoBrowserSmoothZoomAnimator(transitionViewAndFrame: { (index, destinationView) -> JXPhotoBrowserSmoothZoomAnimator.TransitionViewAndFrame? in
    let path = IndexPath(item: index, section: indexPath.section)
    guard let cell = collectionView.cellForItem(at: path) as? BaseCollectionViewCell else {
        return nil
    }
    let image = cell.imageView.image
    let transitionView = UIImageView(image: image)
    transitionView.contentMode = cell.imageView.contentMode
    transitionView.clipsToBounds = true
    let thumbnailFrame = cell.imageView.convert(cell.imageView.bounds, to: destinationView)
    return (transitionView, thumbnailFrame)
})

现在讲解更详细的用法。

JXPhotoBrowserAnimatedTransitioning协议继承自UIViewControllerAnimatedTransitioning,协议声明的3个计算属性都是可选实现。

protocol JXPhotoBrowserAnimatedTransitioning: UIViewControllerAnimatedTransitioning {
    var isForShow: Bool { get set }
    var photoBrowser: JXPhotoBrowser? { get set }
    var isNavigationAnimation: Bool { get set }
}

用户需要自定义转场动画时,关注点仅在实现UIViewControllerAnimatedTransitioning上。isForShowphotoBrowser的值将由JXPhotoBrowser注入,用户可在编写自己的动画实现时获取到它们的值以帮助开发。

Zoom转场动画如果需要百分百过渡顺滑,需要小图和大图的尺寸比例一致,拉伸方式、对齐方式也一致才可以达到视觉上的自然。

具体在代码实现上,需要转场的视图在小尺寸时和缩略图吻合,同时要在放大后和浏览大图吻合。如果缩略图是居中显示的,大图是顶端对齐的,那么转场视图也需要在动画过程中同时调整对齐方式。由于框架无法预实现所有应用场景,同时也为了让用户更灵活地针对自己的应用场景做定制,所以对于这种完美转场效果的需求,JXPhotoBrowserSmoothZoomAnimator要求用户自行创建转场动画视图,以及计算出前后两端的Frame

关于转场动画视图前后两端的Frame,是指基于PhotoBrowser.view的坐标系的Frame。

对于大图端的Frame,只要图片浏览的的项视图遵循了JXPhotoBrowserZoomSupportedCell协议,告诉框架其内容视图对象是哪个,框架即可自动计算出大图端的Frame。

/// 支持Zoom转场的Cell
protocol JXPhotoBrowserZoomSupportedCell: UIView {
    /// 内容视图
    var showContentView: UIView { get }
}

框架提供的作为默认项视图载体的JXPhotoBrowserImageCell已经遵循了SupportedCell协议,如果用户需要自定义Cell,同时希望应用ZoomAnimator,那么需要这个自定义Cell遵循JXPhotoBrowserZoomSupportedCell协议。

对于小图端的Frame,用户需要自行计算出Frame给SmoothZoomAnimator使用。

而实际应用环境中,有可能图片尺寸过大,缩略图被裁剪,这种情况下转场的前后两端是没办法吻合,框架为此做了一种折中方案,分别取小图和大图两端截图,作为两张转场视图叠加在一起,然后同时渐变加缩放,这就是JXPhotoBrowserZoomAnimator,不带Smooth

其实最理想最万能的方案是使用一张图片(视图),让这张图片前期和缩略图重合,随着转场过程逐渐变化,向着大图的形态拟合,结束时和大图重合。遗憾的是我暂时没有高效的实现方案,若有朋友能指点一二,万分感谢~

网图加载

框架不再集成网络图片加载功能,而是让用户自由决定使用适合于自己项目的图片加载方案,比如SDWebImageKingfisher,例子工程皆有基本的使用示范。

// 用SDWebImage加载
browserCell?.imageView.sd_setImage(with: url, placeholderImage: placeholder, options: [], completed: { (_, _, _, _) in
    browserCell?.setNeedsLayout()
})

// 用Kingfisher加载
browserCell?.imageView.kf.setImage(with: url, placeholder: placeholder, options: [], completionHandler: { _ in
    browserCell?.setNeedsLayout()
})

图片加载进度指示器

框架出于业务无关的考虑,对容易受因场景而变更的UI控件都不再集成,但会把示例实现放在例子工程中。

图片加载进度指示器就是这种UI,用户若有需要可自行下载JXPhotoBrowserProgressView

要给项视图(Cell)添加UI,最好是自定义自己的Cell。例子工程示范了如何通过自定义Cell,添加一个图片加载指示器。

class LoadingImageCell: JXPhotoBrowserImageCell {

    let progressView = JXPhotoBrowserProgressView()
    
    override func setup() {
        super.setup()
        addSubview(progressView)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        progressView.center = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
    }
    
    func reloadData(placeholder: UIImage?, urlString: String?) {
        progressView.progress = 0
        let url = urlString.flatMap { URL(string: $0) }
        imageView.sd_setImage(with: url, placeholderImage: placeholder, options: [], progress: { [weak self] (received, total, _) in
            if total > 0 {
                self?.progressView.progress = CGFloat(received) / CGFloat(total)
            }
        }) { [weak self] (_, error, _, _) in
            self?.progressView.progress = error == nil ? 1.0 : 0
            self?.setNeedsLayout()
        }
    }
}

查看原图按钮

查看原图按钮也像图片加载指示器一样是附加UI,框架本身不集成,但是例子工程有实现,用户可结合自己项目修改使用。难点在于控制按钮的隐藏和显现,以及加载使用原图缓存的问题。 详情参考RawImageViewController

页码指示器

考虑到页码指示器的样式基本变化不大,所以框架选择把它们的实现集成进来。 只要是遵循了JXPhotoBrowserPageIndicator协议的类都可以成为PhotoBrowser的页面指示器,把实现类的对象赋值给pageIndicator属性即可。

open var pageIndicator: JXPhotoBrowserPageIndicator?

框架提供了两种页面指示器的实现,当然用户觉得都不满足需求,也可以自己编写,只需要遵循JXPhotoBrowserPageIndicator协议即可。 两种默认实现分别是JXPhotoBrowserDefaultPageIndicatorJXPhotoBrowserNumberPageIndicator

// UIPageIndicator样式的页码指示器
browser.pageIndicator = JXPhotoBrowserDefaultPageIndicator()
// 数字样式的页码指示器
browser.pageIndicator = JXPhotoBrowserNumberPageIndicator()

GIF/WebP图片格式

由于框架把图片加载的权力完全交给了用户,所以加载各种各样图片格式的方案都由用户去选择。各大图片框架皆有特殊图片格式加载的实现,或是自身有实现,或是第三方的实现,用户都可以找到解决方案。

变更数据源

框架支持数据源动态变化,可增加删除数据,然后刷新图片浏览器,就像UITableView一样。

browser.reloadData()

变更数据源的关键在于用户控制好自己的数据一致性,包括要同步缩略图控制器的刷新。

详情查看例子工程的DataSourceDeleteViewControllerDataSourceAppendViewController

跨Section浏览图片

曾经有同学问我这种场景下怎么做,所以我特地举例示范。

这里的意思是指像微信朋友圈(相册)那样,缩略图所在是UICollectionView,有许多个Section,每个Section里有许多图片,当打开图片浏览器的时候需要把所有Section的图片全部一起浏览。

其实这个与PhotoBrowser本身能力无关,PhotoBrowser都是支持的,难点在于用户自己对数据源的处理,要处理好图片浏览器里图片的索引号与数据源里数据的IndexPath的映射关系。

详情可查看MultipleSectionViewController

竖向浏览

框架除了支持像微信图片那样的横向浏览外,还支持像抖音视频那样的竖向浏览。仅设置一个属性即可改变方向,它的默认值是水平横向。

open var scrollDirection: JXPhotoBrowser.ScrollDirection = .horizontal

视频浏览

无论是图片浏览还是视频浏览,于PhotoBrowser来说都是等同的,PhotoBrowser并不知道它的项视图(Cell)承载了什么内容。用户可通过自定义带有播放视频功能的Cell的来达到视频浏览的目的。

框架提供了项视图的生命周期方法,可帮助用户更好地控制视频的播放与停止。

open lazy var cellWillAppear: (JXPhotoBrowserCell, Int) -> Void = { _, _ in }

open lazy var cellWillDisappear: (JXPhotoBrowserCell, Int) -> Void = { _, _ in }

open lazy var cellDidAppear: (JXPhotoBrowserCell, Int) -> Void = { _, _ in }

例子工程有简单的本地视频播放实现,详情可参考VideoPhotoViewController

图片与视频混合浏览

框架允许多个不同的Cell同时存在,允许给每一个项配置不同的类。

任何遵循了JXPhotoBrowserCell协议的类都可以作为PhotoBrowser的项视图。协议仅有一个方法需要实现,就是要求提供生产实例的类方法,框架将会在适当时机通过此方法实例化Cell。

public protocol JXPhotoBrowserCell: UIView {
    static func generate(with browser: JXPhotoBrowser) -> Self
}

对于自定义Cell,遵循了JXPhotoBrowserCell协议后,通过以下方法告诉PhotoBrowser每个index对应使用的类。

browser.cellClassAtIndex = { index in
	// 视频与图片交替展示
	index % 2 == 0 ? VideoCell.self : JXPhotoBrowserImageCell.self
}

框架内部实现了对JXPhotoBrowserCell的复用,即便是同时存在多个自定义Cell类,也只会最小量地生成实例。

视频与图片混合的例子VideoPhotoViewController

某些业务场景需要在最后一页浏览结束后,展示"更多推荐"视图,也是可以的,查看例子MultipleCellViewController

打开方式

框架支持presentpush。通过PhotoBrowser的show(method:)方法打开时,可以传入框架定义的枚举类型。

/// 通过本回调,把图片浏览器嵌套在导航控制器里
public typealias PresentEmbedClosure = (JXPhotoBrowser) -> UINavigationController
    
/// 打开方式类型
public enum ShowMethod {
    case push(inNC: UINavigationController?)
    case present(fromVC: UIViewController?, embed: PresentEmbedClosure?)
}

push

考虑到实际应用场景中,图片浏览器可能需要被嵌入在一个导航控制器里,而且要求使用已有的导航控制器,此时.push枚举能满足这中需求。

// 获取当前导航控制器
let nav = topVC.navigationController 
browser.show(method: .push(inNC: nav))

inNC 可以传nil,此时框架将会尝试自己获取当前顶层的导航控制器,方便用户。

browser.show(method: .push(inNC: nil))

present

如果没有嵌入当前导航控制器里的需要,那么可以使用present

fromVCpresent的发起者,允许传nil值,此时框架将会尝试自己获取当前顶层控制器。 embed允许传入一个新建的导航控制器,也允许nil值,空值时PhotoBrowser将不会嵌入任何导航控制器里。

show(method:)的默认传参是参数皆为nilpresent枚举。

历史版本

2.0版本请参考:Version2.x

1.0版本请参考:Version1.x

初稿文章:ARTICLE

感谢

若使用过程中有任何问题,请issues我。感谢支持 ^_^

photobrowser's People

Contributors

451222664 avatar arabaku avatar gitkun avatar iaugux avatar jiongxing avatar liangdahong avatar strangeliu avatar zer0lu avatar zooyf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

photobrowser's Issues

pod 报错

你好通过pod 报错
可以给出 手动导入的步骤吗

提问

这是为啥?Swift没怎么用过。。。
image

photoBrowserDelegate should use weak property

First issue:

I used photoBrowserDelegate = self. It will called recycle retain and ViewController will not dealloc.
photoBrowserDelegate should use weak property.

This is my code which it's fixed the issue:

before:

public protocol PhotoBrowserDelegate {
}

var photoBrowserDelegate: PhotoBrowserDelegate?

after:

public protocol PhotoBrowserDelegate: class {
}

 weak var photoBrowserDelegate: PhotoBrowserDelegate?

second issue:

Had some UI problem on iPad when i rotate iPad.
This code it not used on iPad.

/// 禁止旋转
    public override var shouldAutorotate: Bool {
        return false
    }

Can u fix it? Thanks man!

相册浏览模式,浏览结束时返场时图片与入场时图片不一致时的问题

场景:
相册模式,启动时是从封面图启动,封面图作为第一张图,当浏览到第二张图片时候返场,这时候原View是没有第二张图片的缩略图的,原View的缩略图是相册封面图,这时候返场动画两张图片切换时就会显得很生硬,请问当前库对这种场景有没有合适的解决方案?

我看了一些的app对类似场景的解决方案【返场时原View没有当前图片时的场景】:
方案1: 返场前会回退到第一张图,然后再开始返场,此时问题解决【Lofter】
方案2: 返场动画会变成渐隐方式,不再缩放到原View缩略图的位置【图虫】

一点建议

1、建议在类的定义以及协议的定义加上@objc关键字方便OC与Swift混编
2、微信的浏览器在放大的情况下也是可以乡下拖拽dismiss

tableView内嵌collectionView的浏览转场动画图片闪烁

在我的tableViewCell内嵌的collectionView中选择除第一个item以外的其他item时,在点击的时候会产生一瞬间图片闪烁的问题,当去掉show方法中的self.modalPresentationStyle = .custom后,问题得以解决,但是效果就没有了,能否告知是何处导致的这个问题,或者希望作者能尝试修复一下

gif问题

加载完gif后,退出后台或杀掉进程,当前的gif就再也播放不了,只显示一张静态图片。

JXPhotoBrowser.show(withImages: [img.image!], currentImageIndex: 0)

你好,初始化的时候可以增加一个方法,只传 要展示的图片数组和当前显示第几张图片就更好了。类似 let _ = JXPhotoBrowser.show(withImages: [img.image!], currentImageIndex: 0),因为我目前一个页面有多组图片预览的地方,如果只用代理的话,判断就很多。

首次滑动Bug

首次进入浏览,用力向右边滑动,页面直接跳到第三页,正常情况应跳到第二页,还请修改一下哈。

关于[查看原图]按钮

效果挺好,有个小问题建议哈:
1、加载过程中可不可以隐藏【查看原图】按钮
2、加载完成 【查看原图】没有自动隐藏
或者给个控制 rawImageButton 显示的属性,不然只能导入源文件,修改源文件。
3q!

数据源中的imageArray没有用吧

JX兄你好:

拜读了你写的关于怎样定制一款图片浏览器的文章,收益良多,研究代码中发现:

数据源中的imageArray 应该是没有用的吧,Cell的内容都是通过url下载的图片么。

借鉴

首先感谢分享,我是来找每个item中间加上分割线的解决办法的,我的需求的是图片混合视频版,其他的准备自己封装了。stared ^_^

建议open class

public class无法子类化,建议open class。
我就不提我的需求点了,子类化就能解决我的问题。
毕竟需求不一样,侧重点不同,一个库实现越多的feature意味着越臃肿。

请问如何得知图片浏览器关闭事件?

非常棒的开源项目,给作者点个赞!

我想在关闭browser后将传入browser的delegate进行释放。
delegate在browser是弱应用,因此在外部需要持有它。
目前的问题是无法得知何时关闭浏览器,导致delegate无法释放。。。

present之后没反应,要再点击一下屏幕才会显示

未命名.mov.zip

如附件录像所示,我点击cell之后调用present,这时候什么都没出现,直到我随便再点击一下屏幕才会出现过渡动画,然后出现图片浏览器。

跑Demo是没问题的。

我的代码如下:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  selectedCell = tableView.cellForRow(at: indexPath)
   showPhotoBrowser(at: index)
}
    /// 显示图片浏览器
    fileprivate func showPhotoBrowser(at index: Int) {
        // 创建图片浏览器
        let browser = PhotoBrowser()
        // 提供两种动画效果:缩放`.scale`和渐变`.fade`。
        browser.animationType = .fade
        // 浏览器协议实现者
        browser.photoBrowserDelegate = self
        // 装配页码指示器插件,提供了两种PageControl实现,若需要其它样式,可参照着自由定制
        // 光点型页码指示器
        browser.plugins.append(DefaultPageControlPlugin())
        // 数字型页码指示器
        browser.plugins.append(NumberPageControlPlugin())
        // 指定打开图片组中的哪张
        browser.originPageIndex = index
        self.present(browser, animated: true, completion: nil)
    }
extension PostDetailVC: PhotoBrowserDelegate {
    
    func numberOfPhotos(in photoBrowser: PhotoBrowser) -> Int {
        return imageURLs!.count
    }
    
    /// 缩放动画起始图,也是图片加载完成前的 placeholder
    func photoBrowser(_ photoBrowser: PhotoBrowser, originImageForIndex index: Int) -> UIImage? {
        return UIImage(.applogo_bigger)
    }
    
    /// 缩放起始视图
    func photoBrowser(_ photoBrowser: PhotoBrowser, originViewForIndex index: Int) -> UIView? {
        return selectedCell
    }
    
    /// 高清图
    func photoBrowser(_ photoBrowser: PhotoBrowser, highQualityUrlForIndex index: Int) -> URL? {
        Log("get", imageURLs?[index])
        return imageURLs?[index]
    }
}

希望能支持下横竖屏

十分感谢作者的开源, 写的也十分好, 希望作者有时间的花可以支持下横竖屏, 谢谢!

有个建议

1、当手指拖动图片不放,往下拉时,可以看到背后的控制器,但是此时控制器的状态栏是隐藏的,微信在此状态下,背后的控制器状态栏是不隐藏的。
2、还有一个需求,能不能新增一个 page 的展示方式,类似新浪微博图片浏览,图片浏览时,page 展示在顶部,样式为 1/9,这样可以让用户自行选择。
之前使用的是另外一个库 SKPhotoBrowser, 也是实现的类似功能,但是没有单击退出,长按回调等接口,所以改用这个库,有问题会及时反馈!

求 react native 版本

RN 一直没有仿微信仿的非常好的原生图片浏览组件,你写的组件如果能封装给 RN 用就好了!

有几个疑问

我看了一下 readme,发现几个问题,望有空解惑。

  1. 下方的 indicator,如果图片数组长度很大,是否没办法有效展示,我参考微信是没有这个组件的
  2. 每张图片传入原图 url 和缩略图 url,那么展示时,我理解是先加载缩略图,然后再加载原图。这里存在一个问题,如果一张图片需要加载两次,这真的有必要么,除非缩略图已被缓存,在这个库中,是否已实现缓存?
  3. 是否有“点击查看原图”,原图 url 肯定不能直接用于下载吧,如果那样做,一张大图可能好几 M 呢...
  4. 左右滑动时图片的间隙,因为我不懂 ios,按我的理解,swiper 设计成每一页放一个组件(包含图片和下方的 indicator),每一页正好占满屏幕,这个间隙塞在哪呢?

急,转场动画不一致的问题

多张图片,点开第一张,然后滑动到第三张的时候,点击图片,按理说最终动画是回到第三张的,目前是回到第一张,就是一开始点击的那一张,如何解决?
可以提供一个代理,指定最后的endFrame吗?谢谢!

Gif 从缓存中读取后,无法播放

/// 取已有图像,若有高清图,只返回高清图,否则返回缩略图和url
private func imageFor(index: Int) -> (UIImage?, URL?) {
if let highQualityImage = photoBrowserDelegate.photoBrowser(self, highQualityImageForIndex: index) {
return (highQualityImage, nil)
}
var highQualityUrl: URL?
if let url = photoBrowserDelegate.photoBrowser(self, highQualityUrlStringForIndex: index) {
var cacheImage: UIImage?
let result = KingfisherManager.shared.cache.isImageCached(forKey: url.cacheKey)
if result.cached, let cacheType = result.cacheType {
switch cacheType {
case .memory:
cacheImage = KingfisherManager.shared.cache.retrieveImageInMemoryCache(forKey: url.cacheKey)
case .disk:
cacheImage = KingfisherManager.shared.cache.retrieveImageInDiskCache(forKey: url.cacheKey)
default:
cacheImage = nil
}
}
if cacheImage != nil {
return (cacheImage!, nil)
}
highQualityUrl = url
}
let thumbnailImage = photoBrowserDelegate.photoBrowser(self, thumbnailImageForIndex: index)
return (thumbnailImage, highQualityUrl)
}

作者真效率。 最近又碰到两种情况:

1、当图片未铺满屏幕时,点击、双击、拖拽图片显示区域以外的黑色区域无响应操作,微信在此种情况下的有响应操作。此需求看是否需要。
2、当图片在放大情况下,拖拽图片,此时图片会突然缩小为原图,有些突兀,微信在此情况下,拖拽时不会突然改变图片大小。看看这个要不要调整。
另外我最近也看了下这个框架,有时间会提交代码

iOS11显示bug

iOS11,iPhone SE(真机、模拟器均有bug),iPhone X模拟器暂无问题,其他机型未测试

bug描述:

图片高度大于等于屏幕高时,可以发现顶部多出了高20px的黑边,图片向下偏移了20px

image

请问在长按方法里如何弹出一个保存图片的小框?

func photoBrowser(_ photoBrowser: PhotoBrowser, didLongPressForIndex index: Int, image: UIImage) {
print("长按,图片size:(image.size)")
imageViewLongPressGestureRecognizer(image)
}

/// 长按图片事件
func imageViewLongPressGestureRecognizer(_ saveImage:UIImage) {
    // 暂时先用 actionSheet 吧
    let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    
    let saveImageAction = UIAlertAction(title: "保存图片", style: .default) { (_) in
        print("保存\(saveImage)")
    }
    let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler: nil)
  
    actionSheet.addAction(saveImageAction)
    actionSheet.addAction(cancelAction)
    present(actionSheet, animated: true, completion: nil)
}

上面这样子提示 下列错误,也无法弹出框
2017-08-30 17:39:46.562 PhotoBrowser[7622:1035904] Warning: Attempt to present <UIAlertController: 0x7fbe2d912cf0> on <PhotoBrowser.MomentsViewController: 0x7fbe2b606020> which is already presenting <JXPhotoBrowser.PhotoBrowser: 0x7fbe2b50e0d0>

关于双击缩放功能

我看目前作者实现的双击缩放,是缩放的一个固定的值。

这与微信或其他主流app的双击缩放有所不同。

所以想问下作者是否有打算调整这个功能, 或者说作者是有意这么做的?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.