Git Product home page Git Product logo

imagescrollview's Introduction

ImageScrollView

This is a control that will help you to display an image, with zoomable and scrollable features easily.

About

When you make an application, which has a photo viewer feature, the photo viewer usually needs to have zoomable and scrollable features, that allows your user viewing photo more details. This control will help you to display images, with zoomable and scrollable features easily.

Demo

Compatible

  • iOS 9 and later.
  • Swift 5.0 and later (for earlier Swift version, please use earlier ImageScrollView version).

Usage

Cocoapod

Add below line to your Podfile:

pod 'ImageScrollView'

then run below command in Terminal to install:

pod install

Note: If the above pod doesn't work, try using below pod definition in Podfile:

pod 'ImageScrollView', :git => 'https://github.com/huynguyencong/ImageScrollView.git'

Swift Package Manager

In Xcode, select menu File -> Swift Packages -> Add Package Dependency. Select a target, then add this link to the input field: https://github.com/huynguyencong/ImageScrollView.git

Manual

Sometimes just want to install manually, just simply add the file ImageSrollView.swift in the folder Sources to your project.

Simple to use

Drag an UIScrollView to your storyboard, change Class and Module in Identity Inspector to ImageScrollView. Also, create an IBOutlet in your source file.

How to config ImageScrollView in storyboard

import ImageScrollView
@IBOutlet weak var imageScrollView: ImageScrollView!
// Important: This setup method should be called once, usually in your viewDidLoad() method
imageScrollView.setup()

let myImage = UIImage(named: "my_image_name")
imageScrollView.display(image: myImage)

That's all. Now try zooming and scrolling to see the result.

You can set delegate to catch event. This delegate is inheritted from UIScrollViewDelegate.

imageScrollView.imageScrollViewDelegate = self
extension ViewController: ImageScrollViewDelegate {
    func imageScrollViewDidChangeOrientation(imageScrollView: ImageScrollView) {
        print("Did change orientation")
    }
    
    func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
        print("scrollViewDidEndZooming at scale \(scale)")
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("scrollViewDidScroll at offset \(scrollView.contentOffset)")
    }
}

Note:

  • If you have any problem about layout, image position, make sure you have called the setup() method of the ImageScrollView. Or you can try calling the method layoutIfNeeded() of the view controller's view:
view.layoutIfNeeded()

About this source

This open source is based on PhotoScroller demo avaiable on Apple's site. The original source was written in Objective C. This open source rewrote it by using Swift, and added some new features:

  • Double tap to zoom.
  • Smoother. Fixed bug when zooming out, the control auto zooms from center, and not from the corner.

License

ImageScrollView is released under the MIT license. See LICENSE for details. Copyright © Nguyen Cong Huy

imagescrollview's People

Contributors

amanida avatar arorajatin avatar ealmdahl avatar huynguyencong avatar jrg-developer avatar liang2kl avatar nightsd01 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

imagescrollview's Issues

swift 2.3 support?

hi there,

im using this library in my project. in order to get it run with xcode 8 and ios 10 i need to have at least swift 2.3 support. do you plan to upgrade this lib to 2.3?

cheers
emre

Xcode compilation errors

/Pods/ImageScrollView/Sources/ImageScrollView.swift:77:28: Type 'UIScrollView.DecelerationRate' (aka 'CGFloat') has no member 'fast'; did you mean 'hash'?

/Pods/ImageScrollView/Sources/ImageScrollView.swift:80:137: 'orientationDidChangeNotification' has been renamed to 'NSNotification.Name.UIDeviceOrientationDidChange'

Can you fix these ( in initialize method ) ?

compile in swift 5

2 compile errs in swift 5 - can you fix ?

private func initialize() {
    showsVerticalScrollIndicator = false
    showsHorizontalScrollIndicator = false
    bouncesZoom = true
    decelerationRate = UIScrollView.DecelerationRate.hash
    delegate = self
    
    NotificationCenter.default.addObserver(self, selector: #selector(ImageScrollView.changeOrientationNotification), name: UIDevice.NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}

FeatureRequest: zoomed Image as variable

I want to use this library so that the user can select his profile image and centre it on himself. Unfortunately, the library doesn't allow to export the image with the current position and zoom level.

Could you make this available or help how I could implement it?

I tried this, but failed:

var zoomedImage: UIImage? {
        
        guard let image = zoomView?.image else {
            return nil
        }
        
        let x = contentOffset.x * zoomScale
        let y = contentOffset.y * zoomScale
        let wh = min(image.size.width, image.size.height) * zoomScale
        
        let croppedImage1 = cropImage(image: image, rect: CGRect(x: x, y: y, width: wh, height: wh))
        print(croppedImage1)

        
        let scaleRect = zoomRectForScale(1 / zoomScale, center: zoomView!.center)
        let croppedImage2 = cropImage(image: image, rect: scaleRect)
        print(croppedImage2)
        
        return croppedImage1
    }
    
    private func cropImage(image: UIImage, rect: CGRect) -> UIImage {
        let cgImage = image.cgImage!
        let croppedCGImage = cgImage.cropping(to: rect)
        return UIImage(cgImage: croppedCGImage!)
    }

Crop visible part of image on screeen

Hey, Thanks for making this library. This is what I was exactly looking for.

I have a query. After zooming to the part of image. I wanted to create another image with the zoomed part of the image within the boundaries of the screen. Like cropping the part that's visible on screen.

How can I get that? I want to save that in a image object and display that later.

Quality loses

Clarity of Image reduces after the image is set in Imagescrollview library. Please Provide a solution of how to display image without loosing image original quality.

Change orientation suggestion

Hello,

I just want to offer you a bit better way to handle size changes. You right frames change not triggered if you change orientation or if autolayouts updated for example :) But bounds definitely got that events :) 

You can easy to handle that by this code

override var bounds: CGRect {
    didSet {
        //Update UI if size of view changed
        if (usedWidth != bounds.width) || (usedHeight != bounds.height)  {
            reloadUI()
        }
    }
}

private func reloadUI() {

    usedWidth = bounds.width
    usedHeight = bounds.height
}

Something like that. I can make real code for you if you want. Thanks for your small and good library :)
Just one more suggestion make imageSize public :) at least for read access :)

Image is not centered on screen after device rotation

Swift 3, Xcode 8, iPhone 6S+, iOS 10.3.3

From your Demo project, the image is not centered on the screen after the device is rotated to and from portrait and landscape mode.

It appears to be that the scrollView is not updating it's size when orientation changes.

2017-09-03 12 29 55
2017-09-03 12 29 58
2017-09-03 12 30 05
2017-09-03 12 30 08

Images look very small

Hello,

It works good when i zoom in or out but at first images look very small.

Check screenshot please
img_3029

How can i fix it ?

Cannot zoom out

Hi, your library seems to be fine, but when I zoom in the image too much I no longer can zoom it out. I mean, I cannot pinch-zoom. The workaround is to double tap.

My view hierarchy is simple:

zrzut ekranu 2019-01-28 o 19 54 22

and here are constraints:

zrzut ekranu 2019-01-28 o 19 54 28

So, I have a view pinned to the sides and top with 1:1 aspect ratio and ImageScrollView inside pinned to all edges (no margin).

Code is also very simple:

override func viewDidLoad() {
        super.viewDidLoad()
        
        imageScrollView.setup()
        
        if let myImage = UIImage(named: "test.png") {
            imageScrollView.display(image: myImage)
        }
}

What could be wrong?

Pod is added like this:

pod 'ImageScrollView', :git => 'https://github.com/huynguyencong/ImageScrollView.git'

because

pod 'ImageScrollView'

just didn't work for me. It was using some old version of the library, where I couldn't even find setup() method.

delegation of scroll/zoom events.

Unless I am missing it, there is no way to grab onto these events as-is. It would seem I need to augment the repo for a new protocol and pass them out as needed. If this is incorrect, please let me know, thank you.

Top content mode

@objc public enum ScaleMode: Int {
        case aspectFill
        case aspectFit
        case widthFill
        case heightFill
}

Only these modes are supported, but how can I use something like "ContentMode.top" so it'll fit the image, but instead of centering it, it'd move the image to the top? I've tried limiting view's height by manually setting up aspect ratio constraint, but then it causes the other issue, which I've described here:

#45

Orientation changes cause zoom to reset

If the user moves their device enough to make it change orientation the zoom size will reset, even when the application is locked to a particular orientation. Could this be turned off if the app is locked? If not maybe adding an option would be a good compromise?

Objective-C Support

Hey,

Nice work on this library. Your library used to work great for Objective-C but it seems to have been broken in one of the latest commits. This happened when you changed to Swift 4.

The displayWithImage method is no longer accessible in Objective-C in its current state. Luckily I was able to fix it just by adding @objc to that method in your code. You might want to add that yourself.

I would submit a pull request but I'm a little low on time :)

Thanks!

Problems with iOS 13.3?

Is anyone else seeing issues since upgrading to iOS 13? The image often doesn't seem to be centered now, especially when running in the iPhone 11 simulator. Note the big gap at the top, which wasn't there before. It should look like the second image by default.

Screen Shot 2019-12-18 at 6 27 12 PM

Screen Shot 2019-12-18 at 6 27 29 PM

Detect when user zoom on image

Hi,
I would like to ask if it is possible to know when the user zooms on the image seen on the screen.
My problem is that every 5 seconds I change the image on the display and I would like this automatic transmission to stop if the user zooms on the image

Thank you

ContentMode Center

If an image loaded into the ImageScrollView is smaller than the frame of the ImageScrollView, is it possible to use UIViewContentMode.center instead of stretching the image to always fill the ImageScrollView frame? I am using the ImageScrollView to display images that my users upload, which could be very small to very large depending on what the user selects. It would be nice is the ImageScrollView had the option to fill the frame if the image is large enough but otherwise not stretch it beyond its original size (at least until the user does a pinch to zoom).

For a regular UIView, I would try something like this:

imageView.contentMode = UIViewContentModeCenter;
if (imageView.bounds.size.width > myView.frame.size.width) && (imageView.bounds.size.height > myView.frame.size.height) {
       imageView.contentMode = UIViewContentModeScaleAspectFit;
}

But this doesn't seem to have any effect on an ImageScrollView.

May I know the purpose of 0.999 technique?

Thank you for this useful library. It saves me countless of hour to implement a zoomable and swipeable image viewer.

However, I am very curious on the following line

https://github.com/huynguyencong/ImageScrollView/blob/master/Sources/ImageScrollView.swift#L248

It seems to me, without 0.999 technique, it will become problematic when this ImageScrollView is placed within UIPageViewController.

I try to implement such, by placing ImageScrollView in UIPageViewController

https://gist.github.com/yccheok/b660cc09b404ae3bab3eb4a586c33cc8

However, I do not find any issue, when I try to change line 248

from

minimumZoomScale = minScale * 0.999

to

minimumZoomScale = minScale

ezgif com-gif-maker

May I know, what problem 0.999 is trying to solve?

Thank you very much

Initializer access level

There is a problem with overriding override init(frame: CGRect) method when ImageScrollView added as separate target via CocoaPods. Only required public init?(coder aDecoder: NSCoder) is accessible but it's not enough when adding control programatically.
Please add public keyword to the second initializer.

Centering inside a NavigationController

I had some issues with centering inside a UIPageController inside a UINavigationController. When a page is rendered it does not always know about the navigationBar and the centering can be off.

I added the following to ImageScrollView to make it render ok. A bit of a hack but it is what I ended up doing so far.

    override open func safeAreaInsetsDidChange() {
        configureImageForSize(imageSize)
        adjustFrameToCenter()
    }

Supports Carthage

I would like to use this library with Carthage.
But, this repo does not have a shared scheme in Xcode Project.
You can support Carthage with adding XcodeProject for Carthage and share build scheme.

<Error>: CGAffineTransformInvert: singular matrix.

Hello,

I am implementing your class and I found it great and very easy to implement but I have the issue mentioned in the title that displays in the console twice each image that I load. Also only the first image gets render the others does not appear.

I am using the file because I have some issues with CocoaPods and I implemented it on a collectionView with custom cells in horizontal layout. Here is the code:

In the cell:
`var albumItem: AlbumItem? {
didSet{

        let image = UIImage(named: (albumItem?.imageName)!)
        
        imageView.display(image: image!)
        
        if albumItem?.type == .video {
            setUpPlayImage()
        }
        
    }
}

let imageView: ImageScrollView = {
    let iv = ImageScrollView()
    let image = UIImage(named: "chiron")
    iv.display(image: image!)
    iv.zoomView?.contentMode = .scaleAspectFill
    iv.clipsToBounds = true
    iv.translatesAutoresizingMaskIntoConstraints = false
    return iv
}()`

In the CollectionViewcontroller:

`override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let singleTap = UITapGestureRecognizer()
    singleTap.numberOfTapsRequired = 1
    //singleTap.require(toFail: doubleTap)
    singleTap.addTarget(self, action: #selector(self.handleTap(gesture:)))
        
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! AlbumItemFullCell
        
    // Configure the cell
    cell.albumItem = albumItems?[indexPath.item]
    cell.playImage.contentMode = .center
    
    cell.backgroundColor = UIColor.getDarkGray()
    
    cell.addGestureRecognizer(singleTap)
    
        
    return cell
    
}`

I noticed the part that the error gets called:

captura de pantalla 2017-01-03 a la s 20 47 19
captura de pantalla 2017-01-03 a la s 20 47 44

But I have no idea why, hope someone know whats happening.

Any way to restore the zoomed image?

Hi there,

is there any way to restore the images zoomscale and contentoffset after re-setting the image, so that the user does not lose the zoomed image when re-opening the view?

I tried to save the zoomScale and contentOffset on viewDidDissappear and re-setting it after using your displayImage() with myScrollImageView.zoomScale = savedZoomScale and the same for contentoffset but it does not work.

Any ideas for that?

cheers and thanks for the nice library!
emre

Improve ImageScrollView to ZoomableScrollView for more general library

Hi, I want to change ImageScrollView to ZoomableScrollView for more general library.

like this.

@objc public private(set) var zoomView: UIImageView? = nil
// to
@objc public private(set) var zoomView: UIView? = nil

@objc open func display(image: UIImage) { ... }
// to
@objc open func display(view: UIView) { ... }
@objc open func display(image: UIImage) {
        let myView = UIImageView(image: image)
        myView!.isUserInteractionEnabled = true
        addSubview(myView)
        display(view: myView)
}

...
and with any other refactoring.

Do you have this kind of plan in this repository?

could you update the demo to show a set zoom level?

It seems too challenging to achieve a simple task: fire up a viewcontroller, set an imagescrollview with a preset zoom and offset.

I know i had it working before, but at present it doesn't seem to want to work.

thank you, drew..

Minor issue with documention

Just starting to test this control.

Noticed when I was setting it up that when you edit the custom class for the ScrollView control you need to set both the Class and the Module to ImageScrollView. If you set only the Class the control crashes at runtime.

Note that the Readme file shows a graphic and only visually boxes the Class. Would be useful and more accurate to have the box highlight both the Class and the Module to avoid the above error.

Looking forward to playing with the control.

Adding programmaticlly using autolayout

When adding the ImageScrollView programmatically using autolayout nothing shows in screen.

let imageScrollView = ImageScrollView()
self.view.addSubview(imageScrollView)
imageScrollView.translatesAutoresizingMaskIntoConstraints = false

imageScrollView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
imageScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
imageScrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
imageScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true

imageScrollView.imageContentMode = .aspectFit
imageScrollView.initialOffset = .center

let image = UIImage(named: "moto", in: Bundle(for: type(of: self)), compatibleWith: nil)
imageScrollView.display(image: image!)

The weird thing in that the sample uses Storyboard to add the ImageScrollView and adds constraints to it.

Set image content mode

How to set image content mode?

I have tried to set image content mode to centre here:

open func display(image: UIImage) {
        .
        .
        .
        zoomView = UIImageView(image: image)
        zoomView?.contentMode = .center
        .
        .
        .
    }

But image is not displaying center.

Images starts of too zoomed in on iPad, not iPhone

I am working on an application that displays images using ImageScrollView, I must say that it is a really good piece of code. I do have a problem however:

I am displaying images that are rectangular and taller than they are wide. On iPhone these start of at a perfect scale but on iPad they are zoomed in so you cannot se the top and bottom parts of the image. It seems like the initial scaling of the image is only considering the width of the ImageScrollView, not the height. I simply want the pictures initial zoom to be scaled to fit inside the ImageScrollView no matter what.

Is it true that only the width of the image is used when calculating the initial scale? If not, can the auto layout constraints be blamed for this. My auto layout constraints for the height of the ImageScrollView is quite a bit more complex.

Imperfect auto-resizing after zooming out too far

This is a very minor issue, but it would be nice when the scale is reset after zooming out too far (when the image is smaller than the frame), if the reset zoom could be pivoted from the centre of the screen rather than the top left - as it looks a bit odd at the moment.

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.