{"id":1518,"url":"https://github.com/alexhillc/AXPhotoViewer","last_synced_at":"2025-08-06T13:32:35.641Z","repository":{"id":44853078,"uuid":"90582987","full_name":"alexhillc/AXPhotoViewer","owner":"alexhillc","description":"An iOS/tvOS photo gallery viewer, useful for viewing a large (or small!) number of photos.","archived":false,"fork":false,"pushed_at":"2024-06-11T00:46:15.000Z","size":5086,"stargazers_count":647,"open_issues_count":34,"forks_count":119,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-10-31T16:25:18.451Z","etag":null,"topics":["browser","gallery","pager","photo","photobrowser","photogallery","photoviewer","slideshow","viewer"],"latest_commit_sha":null,"homepage":"https://www.cocoacontrols.com/controls/axphotoviewer","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexhillc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-08T03:31:13.000Z","updated_at":"2024-10-02T02:02:09.000Z","dependencies_parsed_at":"2024-06-20T10:09:12.438Z","dependency_job_id":"a7d796e5-0149-4379-b5e8-9439a2e79afb","html_url":"https://github.com/alexhillc/AXPhotoViewer","commit_stats":{"total_commits":234,"total_committers":9,"mean_commits":26.0,"dds":"0.17521367521367526","last_synced_commit":"d5ae836691c035075368cf6011d77c2ad754738a"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexhillc%2FAXPhotoViewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexhillc%2FAXPhotoViewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexhillc%2FAXPhotoViewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexhillc%2FAXPhotoViewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexhillc","download_url":"https://codeload.github.com/alexhillc/AXPhotoViewer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228905497,"owners_count":17989778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","gallery","pager","photo","photobrowser","photogallery","photoviewer","slideshow","viewer"],"created_at":"2024-01-05T20:15:48.350Z","updated_at":"2024-12-09T14:30:58.523Z","avatar_url":"https://github.com/alexhillc.png","language":"Swift","funding_links":[],"categories":["Media","Libs","Images [🔝](#readme)","Swift"],"sub_categories":["Image","Images","Other free courses"],"readme":"# This project is unmaintained.\n## Alex passed away in an accident in late 2019. His love of iOS development will always be remembered.\n\n# AXPhotoViewer [![Build Status](https://travis-ci.org/alexhillc/AXPhotoViewer.svg?branch=master)](https://travis-ci.org/alexhillc/AXPhotoViewer)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"http://i.imgur.com/Y3ovA03.gif\" alt=\"Demo GIF #1\"/\u003e\n  \u003cimg src=\"http://i.imgur.com/CCs0TzM.gif\" alt=\"Demo GIF #2\"/\u003e\n\u003c/p\u003e\n\nAXPhotoViewer is an iOS/tvOS photo viewer that is useful for viewing a very large (or very small!) amount of images and GIFs. This library supports contextual presentation and dismissal, interactive \"flick-to-dismiss\" behavior, and easily integrates with many third party async image downloading/caching libraries.\n\n### How to use\nWhile AXPhotoViewer has many configurable properties on each of its modules, it is easy to throw down some initialization code and get started:\n\n```swift\nlet dataSource = AXPhotosDataSource(photos: self.photos)\nlet photosViewController = PhotosViewController(dataSource: dataSource)\nself.present(photosViewController, animated: true)\n```\n\n#### Force touch implementation?\nIt's easy to implement force touch with this library by using `PreviewingPhotosViewController`:\n\n```swift\nfunc previewingContext(_ previewingContext: UIViewControllerPreviewing,\n                      viewControllerForLocation location: CGPoint) -\u003e UIViewController? {\n\n    guard let indexPath = self.tableView.indexPathForRow(at: location),\n        let cell = self.tableView.cellForRow(at: indexPath),\n        let imageView = cell.imageView else {\n        return nil\n    }\n\n    previewingContext.sourceRect = self.tableView.convert(imageView.frame, from: imageView.superview)\n\n    let dataSource = AXPhotosDataSource(photos: self.photos, initialPhotoIndex: indexPath.row)\n    let previewingPhotosViewController = PreviewingPhotosViewController(dataSource: dataSource)\n\n    return previewingPhotosViewController\n}\n\nfunc previewingContext(_ previewingContext: UIViewControllerPreviewing,\n                      commit viewControllerToCommit: UIViewController) {\n\n    if let previewingPhotosViewController = viewControllerToCommit as? PreviewingPhotosViewController {\n        self.present(PhotosViewController(from: previewingPhotosViewController), animated: false)\n    }\n}\n```\n\n### Objective-C interoperability\nThis library fully supports interop between Objective-C and Swift codebases. If you run into any issues with this, please open a Github issue or submit a pull request with the suggested changes.\n\n### Installation\nInstallation can easily be done through Cocoapods:\n```ruby\npod install 'AXPhotoViewer'\n```\nIf you prefer not to use Cocoapods, add the contents of the 'Source' directory to your project to get started.\n\n**Note:** If you don't use Cocoapods, you must add `MobileCoreServices.framework`, `QuartzCore.framework`, and `ImageIO.framework` to your project.\n\n### Configuration\nThere are many configurable properties that can be set before presenting your `AXPhotosViewController`.\n\nFor example, on the `AXPhotoDataSource` object, you may set up the data source with an initial page index, as well as being able to control the rate at which the library will download additional photos.\n\n```swift\nlet photos = [first, second]\nlet dataSource = AXPhotosDataSource(photos: photos, initialPhotoIndex: 1, prefetchBehavior: .aggressive)\n```\n\nOn the `AXPagingConfig` object, you may set up the configuration with a different navigation orientation (horizontal vs vertical scrolling between pages), inter-photo spacing (the spacing, in points, between each photo), and/or a custom loading view class that will be instantiated by the library as needed.\n\n```swift\nlet pagingConfig = AXPagingConfig(navigationOrientation: .horizontal, interPhotoSpacing: 20, loadingViewClass: CustomLoadingView.self)\n```\n\nLastly, but surely not least, is the `AXTransitionInfo` configuration. This can be used to customize all things related to the presentation and dismissal of your `AXPhotosViewController`, including the starting reference view, the ending reference view, the duration of the animations, and a flag to disable/enable interactive dismissals.\n\n```swift\nlet transitionInfo = AXTransitionInfo(interactiveDismissalEnabled: false, startingView: self.startingImageView) { [weak self] (photo, index) -\u003e UIImageView? in\n    // this closure can be used to adjust your UI before returning an `endingImageView`.\n    return self?.endingImageView\n}\n```\n\n### Custom views\nIt's very simple to add a custom self-sizing view to the view hierarchy of the photo viewer by accessing properties on the `OverlayView`. The `topStackContainer` and `bottomStackContainer` are exactly what they sound like, anchored to either the top or bottom of the overlay. All that is necessary to add your custom view to these containers is the following:\n\n```swift\nphotosViewController.overlayView.topStackContainer.addSubview(customSubview1)\nphotosViewController.overlayView.bottomStackContainer.addSubview(customSubview2)\n```\n\nThese views will be sized and stacked in the order that they are added. It's possible to re-order these subviews to fit your needs.\n\n### Network Integrations\nA network integration, in relation to this library, is a class conforming to the `AXNetworkIntegration` protocol. This protocol defines some methods to be used for downloading images, as well as delegating their completions (and errors) to the library. If you wish to create your own module for async downloading/caching of images and gifs, the protocol is fairly lightweight.\n\nSome pre-defined `AXNetworkIntegrations` have already been made as Cocoapod subspecs (SDWebImage, PINRemoteImage, AFNetworking, Kingfisher, Nuke..., as well as a simple network integration using NSURLSession that will serve most people's purposes quite sufficiently). To use these pre-defined subspecs, simply change your `Podfile`:\n\n```ruby\npod install 'AXPhotoViewer/Lite'\npod install 'AXPhotoViewer/SDWebImage'\npod install 'AXPhotoViewer/PINRemoteImage'\npod install 'AXPhotoViewer/AFNetworking'\npod install 'AXPhotoViewer/Kingfisher'\npod install 'AXPhotoViewer/Nuke'\n```\n\nTo create your own `AXNetworkIntegration`:\n```ruby\npod install 'AXPhotoViewer/Core'\n```\n```swift\nlet customNetworkIntegration = CustomNetworkIntegration() // instantiate your custom network integration\nlet dataSource = AXPhotosDataSource(photos: self.photos)\nlet photosViewController = PhotosViewController(dataSource: dataSource, networkIntegration: customNetworkIntegration)\n```\n\n#### Enabling Nuke's support for GIFs\nNuke's support for downloading GIFs is disabled by default. If you want support for GIFs, you have to enabled it.\n\n```swift\nImagePipeline.Configuration.isAnimatedImageDataEnabled = true\n```\n\nMore details here: [Nuke animated images](https://github.com/kean/Nuke#animated-images)\n\n### Customization\nAs mentioned earlier, there are many configurable properties on each of the modules of the photo viewer, and you can access those modules through the `AXPhotosViewController`. For instance, you may replace the default loading view, caption view, and/or overlay title view with your own. These views must be self sizing, and conform to the `AXLoadingViewProtocol`, `AXCaptionViewProtocol`, and `AXOverlayTitleViewProtocol` respectively.\n\n```swift\nlet pagingConfig = AXPagingConfig(loadingViewClass: CustomLoadingView.self) // custom loading view class to be instantiated as necessary\n```\n```swift\n...\nphotosViewController.overlayView.captionView = CustomCaptionView() // custom caption view\nphotosViewController.overlayView.titleView = CustomTitleView() // custom title view\n```\n\nThe `AXPhotosViewController` and its modules are very extensible, so subclassing each is an easy feat to accomplish without breaking other areas of the library.\n\n### Contributions\nIf you see something you would like changed, I'm open to ideas! Open a Github issue if you see something wrong, or fork the repo and open a pull request with your changes. I'd be happy to look them over!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexhillc%2FAXPhotoViewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexhillc%2FAXPhotoViewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexhillc%2FAXPhotoViewer/lists"}