Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to add a fallback image for all ImageSlideshowItem's #184

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions ImageSlideshow/Classes/Core/ImageSlideshow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public protocol ImageSlideshowDelegate: class {
@objc optional func imageSlideshowDidEndDecelerating(_ imageSlideshow: ImageSlideshow)
}

/**
/**
Used to represent position of the Page Control
- hidden: Page Control is hidden
- insideScrollView: Page Control is inside image slideshow
Expand Down Expand Up @@ -145,6 +145,10 @@ open class ImageSlideshow: UIView {
}
}

/// Optional fallbackImage for each InputSource
open var fallbackImage: ImageSource?


/// Current scroll view page. This may differ from `currentPage` as circular slider has two more dummy pages at indexes 0 and n-1 to provide fluent scrolling between first and last item.
open fileprivate(set) var scrollViewPage: Int = 0

Expand Down Expand Up @@ -207,6 +211,9 @@ open class ImageSlideshow: UIView {
}
}

// Fallback content mode for fallbackImage
open var fallbackScaleMode: UIView.ContentMode = .scaleAspectFit

fileprivate var slideshowTimer: Timer?
fileprivate var scrollViewImages = [InputSource]()
fileprivate var isAnimating: Bool = false
Expand Down Expand Up @@ -283,7 +290,8 @@ open class ImageSlideshow: UIView {
pageIndicatorView.isHidden = images.count < 2

var edgeInsets: UIEdgeInsets = UIEdgeInsets.zero
if #available(iOS 11.0, *) {
if #available(iOS 11.0, *),
pageIndicator?.respectSafeAreaInsets ?? true {
edgeInsets = safeAreaInsets
}

Expand Down Expand Up @@ -320,7 +328,7 @@ open class ImageSlideshow: UIView {

var i = 0
for image in scrollViewImages {
let item = ImageSlideshowItem(image: image, zoomEnabled: zoomEnabled, activityIndicator: activityIndicator?.create(), maximumScale: maximumScale)
let item = ImageSlideshowItem(image: image, zoomEnabled: zoomEnabled, activityIndicator: activityIndicator?.create(), maximumScale: maximumScale, fallbackImage: fallbackImage, fallbackScaleMode: fallbackScaleMode)
item.imageView.contentMode = contentScaleMode
slideshowItems.append(item)
scrollView.addSubview(item)
Expand Down
26 changes: 24 additions & 2 deletions ImageSlideshow/Classes/Core/ImageSlideshowItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ open class ImageSlideshowItem: UIScrollView, UIScrollViewDelegate {
/// Input Source for the item
public let image: InputSource

/// Fallback Input Source for the item
public let fallbackImage: InputSource?

/// Scale mode for fallback input source
public let fallbackScaleMode: UIView.ContentMode

/// Guesture recognizer to detect double tap to zoom
open var gestureRecognizer: UITapGestureRecognizer?

Expand Down Expand Up @@ -52,12 +58,16 @@ open class ImageSlideshowItem: UIScrollView, UIScrollViewDelegate {
Initializes a new ImageSlideshowItem
- parameter image: Input Source to load the image
- parameter zoomEnabled: holds if it should be possible to zoom-in the image
- parameter fallbackImage: A fallback image to display if image is unavailable
- parameter fallbackScaleMode: The fallback image scale mode
*/
init(image: InputSource, zoomEnabled: Bool, activityIndicator: ActivityIndicatorView? = nil, maximumScale: CGFloat = 2.0) {
init(image: InputSource, zoomEnabled: Bool, activityIndicator: ActivityIndicatorView? = nil, maximumScale: CGFloat = 2.0, fallbackImage: InputSource? = nil, fallbackScaleMode: UIViewContentMode = .scaleAspectFit) {
self.zoomEnabled = zoomEnabled
self.image = image
self.activityIndicator = activityIndicator
self.maximumScale = maximumScale
self.fallbackImage = fallbackImage
self.fallbackScaleMode = fallbackScaleMode

super.init(frame: CGRect.null)

Expand Down Expand Up @@ -135,7 +145,8 @@ open class ImageSlideshowItem: UIScrollView, UIScrollViewDelegate {

/// Request to load Image Source to Image View
public func loadImage() {
if self.imageView.image == nil && !isLoading {
if (self.imageView.image == nil || self.loadFailed) && !isLoading {
self.imageView.image = nil
isLoading = true
imageReleased = false
activityIndicator?.show()
Expand All @@ -150,6 +161,17 @@ open class ImageSlideshowItem: UIScrollView, UIScrollViewDelegate {
self?.loadFailed = image == nil
self?.isLoading = false

if (self?.loadFailed ?? false) && self?.fallbackImage != nil {
if let imageView = self?.imageView {
self?.fallbackImage?.load(to: imageView) { [weak self] fallbackImage in
imageView.image = (self?.imageReleased ?? false) ? nil : fallbackImage
if let scaleMode = self?.fallbackScaleMode {
imageView.contentMode = scaleMode
}
}
}
}

self?.setNeedsLayout()
}
}
Expand Down
11 changes: 11 additions & 0 deletions ImageSlideshow/Classes/Core/PageIndicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public protocol PageIndicatorView: class {

/// Total number of pages of the page indicator
var numberOfPages: Int { get set}

/// Bool indicating if the page indicator view should respect safe area insets
var respectSafeAreaInsets: Bool { get }
}

extension UIPageControl: PageIndicatorView {
Expand All @@ -33,6 +36,10 @@ extension UIPageControl: PageIndicatorView {
}
}

public var respectSafeAreaInsets: Bool {
return true
}

open override func sizeToFit() {
var frame = self.frame
frame.size = size(forNumberOfPages: numberOfPages)
Expand All @@ -59,6 +66,10 @@ public class LabelPageIndicator: UILabel, PageIndicatorView {
}
}

public var respectSafeAreaInsets: Bool {
return true
}

public override init(frame: CGRect) {
super.init(frame: frame)
initialize()
Expand Down