Skip to content

Commit

Permalink
[PR #129] Added ImageFilter support to UIButton extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
gshahbazian authored and cnoon committed Oct 2, 2016
1 parent 8fd54a9 commit 51dae8f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
25 changes: 21 additions & 4 deletions Source/UIButton+AlamofireImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ extension UIButton {
/// - parameter placeholderImage: The image to be set initially until the image request finished. If `nil`, the
/// image will not change its image until the image request finishes. Defaults
/// to `nil`.
/// - parameter filter: The image filter applied to the image after the image request is finished.
/// Defaults to `nil`.
/// - parameter progress: The closure to be executed periodically during the lifecycle of the request.
/// Defaults to `nil`.
/// - parameter progressQueue: The dispatch queue to call the progress closure on. Defaults to the main queue.
Expand All @@ -123,6 +125,7 @@ extension UIButton {
for state: UIControlState,
url: URL,
placeholderImage: UIImage? = nil,
filter: ImageFilter? = nil,
progress: ImageDownloader.ProgressHandler? = nil,
progressQueue: DispatchQueue = DispatchQueue.main,
completion: ((DataResponse<UIImage>) -> Void)? = nil)
Expand All @@ -131,6 +134,7 @@ extension UIButton {
for: state,
urlRequest: urlRequest(with: url),
placeholderImage: placeholderImage,
filter: filter,
progress: progress,
progressQueue: progressQueue,
completion: completion
Expand All @@ -147,6 +151,8 @@ extension UIButton {
/// - parameter placeholderImage: The image to be set initially until the image request finished. If `nil`, the
/// image will not change its image until the image request finishes. Defaults
/// to `nil`.
/// - parameter filter: The image filter applied to the image after the image request is finished.
/// Defaults to `nil`.
/// - parameter progress: The closure to be executed periodically during the lifecycle of the request.
/// Defaults to `nil`.
/// - parameter progressQueue: The dispatch queue to call the progress closure on. Defaults to the main queue.
Expand All @@ -158,6 +164,7 @@ extension UIButton {
for state: UIControlState,
urlRequest: URLRequestConvertible,
placeholderImage: UIImage? = nil,
filter: ImageFilter? = nil,
progress: ImageDownloader.ProgressHandler? = nil,
progressQueue: DispatchQueue = DispatchQueue.main,
completion: ((DataResponse<UIImage>) -> Void)? = nil)
Expand All @@ -172,7 +179,7 @@ extension UIButton {
// Use the image from the image cache if it exists
if
let request = urlRequest.urlRequest,
let image = imageCache?.image(for: request, withIdentifier: nil)
let image = imageCache?.image(for: request, withIdentifier: filter?.identifier)
{
let response = DataResponse<UIImage>(
request: urlRequest.urlRequest,
Expand All @@ -197,7 +204,7 @@ extension UIButton {
let requestReceipt = imageDownloader.download(
urlRequest,
receiptID: downloadID,
filter: nil,
filter: filter,
progress: progress,
progressQueue: progressQueue,
completion: { [weak self] response in
Expand Down Expand Up @@ -245,6 +252,8 @@ extension UIButton {
/// - parameter placeholderImage: The image to be set initially until the image request finished. If `nil`, the
/// background image will not change its image until the image request finishes.
/// Defaults to `nil`.
/// - parameter filter: The image filter applied to the image after the image request is finished.
/// Defaults to `nil`.
/// - parameter progress: The closure to be executed periodically during the lifecycle of the request.
/// Defaults to `nil`.
/// - parameter progressQueue: The dispatch queue to call the progress closure on. Defaults to the main queue.
Expand All @@ -256,6 +265,7 @@ extension UIButton {
for state: UIControlState,
url: URL,
placeholderImage: UIImage? = nil,
filter: ImageFilter? = nil,
progress: ImageDownloader.ProgressHandler? = nil,
progressQueue: DispatchQueue = DispatchQueue.main,
completion: ((DataResponse<UIImage>) -> Void)? = nil)
Expand All @@ -264,7 +274,11 @@ extension UIButton {
for: state,
urlRequest: urlRequest(with: url),
placeholderImage: placeholderImage,
completion: completion)
filter: filter,
progress: progress,
progressQueue: progressQueue,
completion: completion
)
}

/// Asynchronously downloads an image from the specified URL request and sets it once the request is finished.
Expand All @@ -277,6 +291,8 @@ extension UIButton {
/// - parameter placeholderImage: The image to be set initially until the image request finished. If `nil`, the
/// background image will not change its image until the image request finishes.
/// Defaults to `nil`.
/// - parameter filter: The image filter applied to the image after the image request is finished.
/// Defaults to `nil`.
/// - parameter progress: The closure to be executed periodically during the lifecycle of the request.
/// Defaults to `nil`.
/// - parameter progressQueue: The dispatch queue to call the progress closure on. Defaults to the main queue.
Expand All @@ -288,6 +304,7 @@ extension UIButton {
for state: UIControlState,
urlRequest: URLRequestConvertible,
placeholderImage: UIImage? = nil,
filter: ImageFilter? = nil,
progress: ImageDownloader.ProgressHandler? = nil,
progressQueue: DispatchQueue = DispatchQueue.main,
completion: ((DataResponse<UIImage>) -> Void)? = nil)
Expand All @@ -302,7 +319,7 @@ extension UIButton {
// Use the image from the image cache if it exists
if
let request = urlRequest.urlRequest,
let image = imageCache?.image(for: request, withIdentifier: nil)
let image = imageCache?.image(for: request, withIdentifier: filter?.identifier)
{
let response = DataResponse<UIImage>(
request: urlRequest.urlRequest,
Expand Down
50 changes: 50 additions & 0 deletions Tests/UIButtonTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,28 @@ class UIButtonTests: BaseTestCase {
XCTAssertTrue(secondEqualityCheck, "second equality check should be true")
}

func testThatImageCanBeLoadedFromImageCacheFromRequestAndFilterIdentifierIfAvailable() {
// Given
let button = UIButton()

let downloader = ImageDownloader.default
let download = try! URLRequest(url: url.absoluteString, method: .get)
let expectation = self.expectation(description: "image download should succeed")

downloader.download(download, filter: CircleFilter()) { (_) in
expectation.fulfill()
}

waitForExpectations(timeout: timeout, handler: nil)

// When
button.af_setImage(for: .normal, url: url, filter: CircleFilter())
button.af_cancelImageRequest(for: .normal)

// Then
XCTAssertNotNil(button.image(for: .normal), "image view image should not be nil")
}

// MARK: - Placeholder Images

func testThatPlaceholderImageIsDisplayedUntilImageIsDownloadedFromURL() {
Expand Down Expand Up @@ -491,6 +513,34 @@ class UIButtonTests: BaseTestCase {
XCTAssertFalse(button.backgroundImage(for:[]) === placeholderImage, "button background image should not equal placeholder image")
}

// MARK: - Image Filters

func testThatImageFilterCanBeAppliedToDownloadedImageBeforeBeingDisplayed() {
// Given
let size = CGSize(width: 20, height: 20)
let filter = ScaledToSizeFilter(size: size)

let expectation = self.expectation(description: "image download should succeed")
var imageDownloadComplete = false

let button = TestButton {
imageDownloadComplete = true
expectation.fulfill()
}

// When
button.af_setImage(for: .normal, url: url, filter: filter)
waitForExpectations(timeout: timeout, handler: nil)

// Then
XCTAssertTrue(imageDownloadComplete, "image download complete should be true")
XCTAssertNotNil(button.image(for: .normal), "image view image should not be nil")

if let image = button.image(for: .normal) {
XCTAssertEqual(image.size, size, "image size does not match expected value")
}
}

// MARK: - Completion Handler

func testThatCompletionHandlerIsCalledWhenImageDownloadSucceeds() {
Expand Down

0 comments on commit 51dae8f

Please sign in to comment.