{"id":15293558,"url":"https://github.com/egzonpllana/interactiveimageview","last_synced_at":"2025-04-13T13:31:13.692Z","repository":{"id":57897162,"uuid":"528990531","full_name":"egzonpllana/InteractiveImageView","owner":"egzonpllana","description":"Simple UIView to interact with an Image view like scroll, zoom, pinch and crop.","archived":false,"fork":false,"pushed_at":"2024-05-25T10:19:12.000Z","size":43837,"stargazers_count":50,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T01:58:51.552Z","etag":null,"topics":["crop","image","imageeditor","ios","pinch","scroll","swift","zoom"],"latest_commit_sha":null,"homepage":"","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/egzonpllana.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-08-25T19:26:02.000Z","updated_at":"2025-03-26T11:10:08.000Z","dependencies_parsed_at":"2022-09-24T18:22:32.831Z","dependency_job_id":"a97939af-9a68-4170-b9b6-0915536fd347","html_url":"https://github.com/egzonpllana/InteractiveImageView","commit_stats":{"total_commits":95,"total_committers":2,"mean_commits":47.5,"dds":0.1578947368421053,"last_synced_commit":"3a251414e51d5c07bb523884d98f77275ef78e43"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egzonpllana%2FInteractiveImageView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egzonpllana%2FInteractiveImageView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egzonpllana%2FInteractiveImageView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egzonpllana%2FInteractiveImageView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egzonpllana","download_url":"https://codeload.github.com/egzonpllana/InteractiveImageView/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248721009,"owners_count":21151026,"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":["crop","image","imageeditor","ios","pinch","scroll","swift","zoom"],"created_at":"2024-09-30T16:49:57.995Z","updated_at":"2025-04-13T13:31:08.681Z","avatar_url":"https://github.com/egzonpllana.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"logo.png\" width=\"300\" max-width=\"50%\" alt=“InteractiveImageView” /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-5.0-orange.svg\" /\u003e\n    \u003ca href=\"https://cocoapods.org/pods/InteractiveImageView\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/v/InteractiveImageView.svg\" alt=\"CocoaPods\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/carthage-compatible-4BC51D.svg?style=flat\" alt=\"Carthage\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://swift.org/package-manager\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=flat\" alt=\"Swift Package Manager\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nWelcome to **Interactive Image View**, a simple library that provides an easier way to interact with image view, like scroll, zoom and crop. In its core it support two image content mode, the one is always square and the second one is custom. For example you can use aspect ration like instagram does 2:3 or 9:16, or any custom value. Basically, it's a thin wrapper around the `UIScrollView` and `UIImageView` APIs that `UIKit` provides.\n\n## Features\n\n- [X] Use at any place as UIView, no need to present or configure a viewcontroller.\n- [X] Crop image at current position as user wants.\n- [X] Switch between aspect ration, 2:3 or 1:1, same as Instagram.\n- [X] Can be extended to support different aspect rations.\n- [X] Scroll image view on x and y axis.\n- [X] Double tap to zoom in or zoom out.\n- [X] Rotate image by given degrees.\n- [X] Pinch image view.\n\n### Preview\n\u003cp align=\"left\"\u003e\n    \u003cimg src=\"example-preview.gif\" width=\"380\" max-height=\"50%\" alt=“InteractiveImageView” /\u003e\n\u003c/p\u003e\n\n## Setup\n\n1. Add a view, and set the class of the view to `InteractiveImageView`.\n2. In your view controller, import InteractiveImageView.\n3. Connect view outlet, configure it with `interactiveImageView.configure(...)`\n4. Add delegates `interactiveImageView.delegate = self`\n5. Listen to delegate observers: `extension ViewController: InteractiveImageViewDelegate { ... }`\n        \n## Methods\n#### Configure view\n```swift\nif let image = UIImage(named: \"image.png\") {\n    interactiveImageView.configure(withNextContentMode: .heightFill,\n                      withFocusOffset: .center,\n                      withImage: image)\n}\n```\n#### Crop and get image without delegate methods\n```swift\nlet croppedImage = interactiveImageView.cropAndGetImage()\n```\n#### Get original image without any modification on it.\n```swift\nlet originalImage = interactiveImageView.getOriginalImage()\n```\n#### Set only image in the ImageView.\n```swift\ninteractiveImageView.updateImageView(withImage image: UIImage?)\n```\n#### Update image in the ImageView.\n```swift\ninteractiveImageView.uupdateImageOnly(_ image: UIImage?)\n```\n#### Toggle image content mode\n```swift\ninteractiveImageView.toggleImageContentMode()\n```\n#### Rotate image\n```swift\ninteractiveImageView.rotateImage(UIImage, keepChanges: Bool)\n```\n\n## User gestures\n#### Double tap to zoom gesture\n```swift\ninteractiveImageView.isDoubleTapToZoomAllowed = false\n```\n#### Scroll view\n```swift\ninteractiveImageView.isScrollEnabled = false\n```\n#### Pinch to zoom gesture\n```swift\ninteractiveImageView.isPinchAllowed = false\n```\n## Delegate methods\n```swift\nprotocol InteractiveImageViewDelegate: AnyObject {\n    func didCropImage(image: UIImage, fromView: InteractiveImageView)\n    func didScrollAt(offset: CGPoint, scale: CGFloat, fromView: InteractiveImageView)\n    func didZoomAt(offset: CGPoint, scale: CGFloat, fromView: InteractiveImageView)\n    func didFail(_ fail: IIVFailType)\n}\n```\n\n## Example Project\nYou can download and run example project `InteractiveImageViewExample`.\n\n## Installation\n\n### CocoaPods\n\n[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate InteractiveImageView into your Xcode project using CocoaPods, specify it in your `Podfile`:\n\n```ruby\npod 'InteractiveImageView'\n```\n\n### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate InteractiveImageView into your Xcode project using Carthage, specify it in your `Cartfile`:\n\n```ogdl\ngithub \"egzonpllana/InteractiveImageView\"\n```\n\n### Swift Package Manager through Manifest File\n\nThe [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler.\n\nOnce you have your Swift package set up, adding InteractiveImageView as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/egzonpllana/InteractiveImageView.git\", .upToNextMajor(from: \"1.0.0\"))\n]\n```\n\n### Swift Package Manager through XCode\nTo add InteractiveImageView as a dependency to your Xcode project, select File \u003e Swift Packages \u003e Add Package Dependency and enter the repository URL\n```ogdl\nhttps://github.com/egzonpllana/InteractiveImageView.git\n```\n\n## Backstory\n\nSo, why was this made? While I was working on a project to provide an interactive image view based on given aspect ration, I could not find a suitable solution that offers all in one these features working in a single view without a need for a viewcontroller, so I build it.\n\n## Questions or feedback?\n\nFeel free to [open an issue](https://github.com/egzonpllana/InteractiveImageView/issues/new), or find me [@egzonpllana on LinkedIn](https://www.linkedin.com/in/egzon-pllana/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegzonpllana%2Finteractiveimageview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegzonpllana%2Finteractiveimageview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegzonpllana%2Finteractiveimageview/lists"}