Krisiacik / ImageViewer

An image viewer à la Twitter
MIT License
2.53k stars 385 forks source link

Avoiding the activity view when using a displacedView and a network request #144

Open Ricardo1980 opened 7 years ago

Ricardo1980 commented 7 years ago

Hello,

Right now, I am using displacedView and in: public func provideGalleryItem(_ index: Int) -> GalleryItem { I send a network request to get a higher resolution version.

The thing is, after the displacedView animation is completed, that image is removed, and a activity view is presented. After a couple of seconds, I see again the same image (with higher resolution).

Is it possible to avoid removing displacedView to show the activity view?

I see in ItemBaseController, in method presentItem, that this is called after the displacedView animation: animatedImageView.removeFromSuperview() I guess that's the problem. If I comment that line, it appears it is working, but I should remove that view later, after the network request is completed. Should I subclass ItemBaseController.swift? Apart from that, it seems the animatedImageView is not in the scrollview, so if I try to dismiss the view, that image does not move.

See current behaviour: viewer mov

Here my provideGalleryItem function, that basically sends a network request:

public func provideGalleryItem(_ index: Int) -> GalleryItem {

    if let image = self.dataSource?.image?(index: index, galleryViewerInteractor: self) {
        return GalleryItem.image { callback in
            callback(image)
        }

    } else if let imageURL = self.dataSource?.imageURL?(index: index, galleryViewerInteractor: self) {
        return GalleryItem.image { callback in
            SDWebImageManager().loadImage(with: imageURL,
                                          options: .highPriority,
                                          progress: nil) { image, data, error, cacheType, finished, imageURL in
                if image != nil && finished {
                    callback(image)
                }
            }
        }

    } else {
        let errorString = "No Local or Remote image found. Displaying a placeholder instead."
        assertionFailure(errorString)
        Crashlytics.sharedInstance().recordNonFatalErrorString(errorString)
        return GalleryItem.image { callback in
            callback(UIImage(named: "image_placeholder")!)
        }
    }
}

Any suggestion? Thanks.

izhylenko commented 7 years ago

I've faced with the same problem. And I've found some kind of workaround. Instead of commenting out the line: animatedImageView.removeFromSuperview()

I've added several lines to set an temp image to itemView, like that:

...
completion: { [weak self] _ in

                        self?.itemView.isHidden = false

                        **if self?.itemView.image == nil {
                            self?.itemView.image = animatedImageView.image
                        }**
                        displacedView.hidden = false
                        animatedImageView.removeFromSuperview()

                        self?.isAnimating = false
                        completion()
                    })
...

By doing this temp low resolution image from an animated source is set to itemView, after animating image is not gone and an activity indicator is displayed over this image. And after fetchImage block is completed and high res image is loaded it just changes temp low res image with needed one. And while hires image is loading you still able to swipe to dismiss image viewer.

For the ImageView author, maybe this kind of setting should be added to avoid such situations? What do you think?

BadReese commented 7 years ago

@izhylenko

aalenliang commented 6 years ago

Same issue here, It's better if ImageViewer can keep my low resolution image when loading, replace it with the higher resolution image after it's downloaded.