Skip to content

Commit

Permalink
Update docs for SwiftUI
Browse files Browse the repository at this point in the history
  • Loading branch information
onevcat committed Oct 25, 2023
1 parent 7afb484 commit ba33e27
Show file tree
Hide file tree
Showing 14 changed files with 414 additions and 307 deletions.
189 changes: 98 additions & 91 deletions Sources/Extensions/ImageView+Kingfisher.swift

Large diffs are not rendered by default.

68 changes: 33 additions & 35 deletions Sources/Extensions/NSButton+Kingfisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,21 @@ extension KingfisherWrapper where Base: NSButton {

// MARK: Setting Image

/// Sets an image to the button with a source.
/// Sets an image to the button with a ``Source``.
///
/// - Parameters:
/// - source: The `Source` object contains information about how to get the image.
/// - placeholder: A placeholder to show while retrieving the image from the given `resource`.
/// - options: An options set to define image setting behaviors. See `KingfisherOptionsInfo` for more.
/// - progressBlock: Called when the image downloading progress gets updated. If the response does not contain an
/// - source: The ``Source`` object that defines data information from the network or a data provider.
/// - placeholder: A placeholder to show while retrieving the image from the given `source`.
/// - options: A set of options to define image setting behaviors. See ``KingfisherOptionsInfo`` for more.
/// - progressBlock: Called when the image downloading progress is updated. If the response does not contain an
/// `expectedContentLength`, this block will not be called.
/// - completionHandler: Called when the image retrieved and set finished.
/// - Returns: A task represents the image downloading.
/// - completionHandler: Called when the image retrieval and setting are finished.
/// - Returns: A task that represents the image downloading.
///
/// - Note:
/// Internally, this method will use `KingfisherManager` to get the requested source.
/// Since this method will perform UI changes, you must call it from the main thread.
/// Both `progressBlock` and `completionHandler` will be also executed in the main thread.
/// Internally, this method will use ``KingfisherManager`` to get the source. Since this method will perform UI
/// changes, it is your responsibility to call it from the main thread.
///
/// > Both `progressBlock` and `completionHandler` will also be executed in the main thread.
@discardableResult
public func setImage(
with source: Source?,
Expand All @@ -66,22 +65,21 @@ extension KingfisherWrapper where Base: NSButton {
)
}

/// Sets an image to the button with a requested resource.
/// Sets an image to the button with a ``Resource``.
///
/// - Parameters:
/// - resource: The `Resource` object contains information about the resource.
/// - placeholder: A placeholder to show while retrieving the image from the given `resource`.
/// - options: An options set to define image setting behaviors. See `KingfisherOptionsInfo` for more.
/// - progressBlock: Called when the image downloading progress gets updated. If the response does not contain an
/// - resource: The ``Resource`` object that defines data information from the network or a data provider.
/// - placeholder: A placeholder to show while retrieving the image from the given `source`.
/// - options: A set of options to define image setting behaviors. See ``KingfisherOptionsInfo`` for more.
/// - progressBlock: Called when the image downloading progress is updated. If the response does not contain an
/// `expectedContentLength`, this block will not be called.
/// - completionHandler: Called when the image retrieved and set finished.
/// - Returns: A task represents the image downloading.
/// - completionHandler: Called when the image retrieval and setting are finished.
/// - Returns: A task that represents the image downloading.
///
/// - Note:
/// Internally, this method will use `KingfisherManager` to get the requested resource, from either cache
/// or network. Since this method will perform UI changes, you must call it from the main thread.
/// Both `progressBlock` and `completionHandler` will be also executed in the main thread.
/// Internally, this method will use ``KingfisherManager`` to get the source. Since this method will perform UI
/// changes, it is your responsibility to call it from the main thread.
///
/// > Both `progressBlock` and `completionHandler` will also be executed in the main thread.
@discardableResult
public func setImage(
with resource: Resource?,
Expand Down Expand Up @@ -196,22 +194,21 @@ extension KingfisherWrapper where Base: NSButton {
)
}

/// Sets an alternate image to the button with a requested resource.
/// Sets an alternate image to the button with a ``Resource``.
///
/// - Parameters:
/// - resource: The `Resource` object contains information about the resource.
/// - placeholder: A placeholder to show while retrieving the image from the given `resource`.
/// - options: An options set to define image setting behaviors. See `KingfisherOptionsInfo` for more.
/// - progressBlock: Called when the image downloading progress gets updated. If the response does not contain an
/// - resource: The ``Resource`` object that defines data information from the network or a data provider.
/// - placeholder: A placeholder to show while retrieving the image from the given `source`.
/// - options: A set of options to define image setting behaviors. See ``KingfisherOptionsInfo`` for more.
/// - progressBlock: Called when the image downloading progress is updated. If the response does not contain an
/// `expectedContentLength`, this block will not be called.
/// - completionHandler: Called when the image retrieved and set finished.
/// - Returns: A task represents the image downloading.
/// - completionHandler: Called when the image retrieval and setting are finished.
/// - Returns: A task that represents the image downloading.
///
/// - Note:
/// Internally, this method will use `KingfisherManager` to get the requested resource, from either cache
/// or network. Since this method will perform UI changes, you must call it from the main thread.
/// Both `progressBlock` and `completionHandler` will be also executed in the main thread.
/// Internally, this method will use ``KingfisherManager`` to get the source. Since this method will perform UI
/// changes, it is your responsibility to call it from the main thread.
///
/// > Both `progressBlock` and `completionHandler` will also be executed in the main thread.
@discardableResult
public func setAlternateImage(
with resource: Resource?,
Expand Down Expand Up @@ -255,7 +252,7 @@ extension KingfisherWrapper where Base: NSButton {
options.onDataReceived = (options.onDataReceived ?? []) + [ImageLoadingProgressSideEffect(block)]
}

if let provider = ImageProgressiveProvider(options, refresh: { image in
if let provider = ImageProgressiveProvider(options: options, refresh: { image in
self.base.alternateImage = image
}) {
options.onDataReceived = (options.onDataReceived ?? []) + [provider]
Expand Down Expand Up @@ -308,7 +305,8 @@ extension KingfisherWrapper where Base: NSButton {

// MARK: Cancelling Alternate Image Downloading Task

/// Cancels the alternate image download task of the button if it is running.
/// Cancels the image download task of the image view if it is running.
///
/// Nothing will happen if the downloading has already finished.
public func cancelAlternateImageDownloadTask() {
alternateImageTask?.cancel()
Expand Down
71 changes: 35 additions & 36 deletions Sources/Extensions/NSTextAttachment+Kingfisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,31 @@ extension KingfisherWrapper where Base: NSTextAttachment {
/// Sets an image to the text attachment with a source.
///
/// - Parameters:
/// - source: The `Source` object defines data information from network or a data provider.
/// - attributedView: The owner of the attributed string which this `NSTextAttachment` is added.
/// - placeholder: A placeholder to show while retrieving the image from the given `resource`.
/// - options: An options set to define image setting behaviors. See `KingfisherOptionsInfo` for more.
/// - progressBlock: Called when the image downloading progress gets updated. If the response does not contain an
/// - source: The ``Source`` object that defines data information from the network or a data provider.
/// - attributedView: The owner of the attributed string to which this `NSTextAttachment` is added.
/// - placeholder: A placeholder to show while retrieving the image from the given `source`.
/// - options: A set of options to define image setting behaviors. See ``KingfisherOptionsInfo`` for more.
/// - progressBlock: Called when the image downloading progress is updated. If the response does not contain an
/// `expectedContentLength`, this block will not be called.
/// - completionHandler: Called when the image retrieved and set finished.
/// - Returns: A task represents the image downloading.
///
/// - Note:
/// - completionHandler: Called when the image retrieval and setting are finished.
/// - Returns: A task that represents the image downloading.
///
/// Internally, this method will use `KingfisherManager` to get the requested source
/// Since this method will perform UI changes, you must call it from the main thread.
/// Internally, this method will use ``KingfisherManager`` to get the requested source. Since this method will
/// perform UI changes, it is your responsibility of calling it from the main thread.
///
/// The retrieved image will be set to `NSTextAttachment.image` property. Because it is not an image view based
/// rendering, options related to view, such as `.transition`, are not supported.
/// The retrieved image will be set to the `NSTextAttachment.image` property. Because it is not an image view-based
/// rendering, options related to the view, such as ``KingfisherOptionsInfoItem/transition(_:)``, are not supported.
///
/// Kingfisher will call `setNeedsDisplay` on the `attributedView` when the image task done. It gives the view a
/// Kingfisher will call `setNeedsDisplay` on the `attributedView` when the image task is done. It gives the view a
/// chance to render the attributed string again for displaying the downloaded image. For example, if you set an
/// attributed with this `NSTextAttachment` to a `UILabel` object, pass it as the `attributedView` parameter.
/// attributed string with this `NSTextAttachment` to a `UILabel` object, pass it as the `attributedView` parameter.
///
/// Here is a typical use case:
///
/// ```swift
/// let attributedText = NSMutableAttributedString(string: "Hello World")
/// let textAttachment = NSTextAttachment()
/// let label: UILabel = // ...
///
/// let textAttachment = NSTextAttachment()
/// textAttachment.kf.setImage(
/// with: URL(string: "https://onevcat.com/assets/images/avatar.jpg")!,
/// attributedView: label,
Expand All @@ -75,10 +73,11 @@ extension KingfisherWrapper where Base: NSTextAttachment {
/// |> RoundCornerImageProcessor(cornerRadius: 15))
/// ]
/// )
///
/// let attributedText = NSMutableAttributedString(string: "Hello World")
/// attributedText.replaceCharacters(in: NSRange(), with: NSAttributedString(attachment: textAttachment))
/// label.attributedText = attributedText
/// ```
///
@discardableResult
public func setImage(
with source: Source?,
Expand All @@ -102,33 +101,31 @@ extension KingfisherWrapper where Base: NSTextAttachment {
/// Sets an image to the text attachment with a source.
///
/// - Parameters:
/// - resource: The `Resource` object contains information about the resource.
/// - attributedView: The owner of the attributed string which this `NSTextAttachment` is added.
/// - resource: The ``Resource`` object that defines data information from the network or a data provider.
/// - attributedView: The owner of the attributed string to which this `NSTextAttachment` is added.
/// - placeholder: A placeholder to show while retrieving the image from the given `resource`.
/// - options: An options set to define image setting behaviors. See `KingfisherOptionsInfo` for more.
/// - progressBlock: Called when the image downloading progress gets updated. If the response does not contain an
/// - options: A set of options to define image setting behaviors. See ``KingfisherOptionsInfo`` for more.
/// - progressBlock: Called when the image downloading progress is updated. If the response does not contain an
/// `expectedContentLength`, this block will not be called.
/// - completionHandler: Called when the image retrieved and set finished.
/// - Returns: A task represents the image downloading.
/// - completionHandler: Called when the image retrieval and setting are finished.
/// - Returns: A task that represents the image downloading.
///
/// - Note:
/// Internally, this method will use ``KingfisherManager`` to get the requested source. Since this method will
/// perform UI changes, it is your responsibility of calling it from the main thread.
///
/// Internally, this method will use `KingfisherManager` to get the requested source
/// Since this method will perform UI changes, you must call it from the main thread.
/// The retrieved image will be set to the `NSTextAttachment.image` property. Because it is not an image view-based
/// rendering, options related to the view, such as ``KingfisherOptionsInfoItem/transition(_:)``, are not supported.
///
/// The retrieved image will be set to `NSTextAttachment.image` property. Because it is not an image view based
/// rendering, options related to view, such as `.transition`, are not supported.
///
/// Kingfisher will call `setNeedsDisplay` on the `attributedView` when the image task done. It gives the view a
/// Kingfisher will call `setNeedsDisplay` on the `attributedView` when the image task is done. It gives the view a
/// chance to render the attributed string again for displaying the downloaded image. For example, if you set an
/// attributed with this `NSTextAttachment` to a `UILabel` object, pass it as the `attributedView` parameter.
/// attributed string with this `NSTextAttachment` to a `UILabel` object, pass it as the `attributedView` parameter.
///
/// Here is a typical use case:
///
/// ```swift
/// let attributedText = NSMutableAttributedString(string: "Hello World")
/// let textAttachment = NSTextAttachment()
/// let label: UILabel = // ...
///
/// let textAttachment = NSTextAttachment()
/// textAttachment.kf.setImage(
/// with: URL(string: "https://onevcat.com/assets/images/avatar.jpg")!,
/// attributedView: label,
Expand All @@ -138,10 +135,11 @@ extension KingfisherWrapper where Base: NSTextAttachment {
/// |> RoundCornerImageProcessor(cornerRadius: 15))
/// ]
/// )
///
/// let attributedText = NSMutableAttributedString(string: "Hello World")
/// attributedText.replaceCharacters(in: NSRange(), with: NSAttributedString(attachment: textAttachment))
/// label.attributedText = attributedText
/// ```
///
@discardableResult
public func setImage(
with resource: Resource?,
Expand Down Expand Up @@ -238,7 +236,8 @@ extension KingfisherWrapper where Base: NSTextAttachment {

// MARK: Cancelling Image

/// Cancel the image download task bounded to the text attachment if it is running.
/// Cancel the image download task bound to the text attachment if it is running.
///
/// Nothing will happen if the downloading has already finished.
public func cancelDownloadTask() {
imageTask?.cancel()
Expand Down
2 changes: 1 addition & 1 deletion Sources/Image/ImageDrawing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ extension KingfisherWrapper where Base: KFCrossPlatformImage {
return base
}

#if !os(watchOS)
#if !os(watchOS) && !os(macOS)
// In newer system versions, use `preparingForDisplay`.
if #available(iOS 15.0, tvOS 15.0, visionOS 1.0, *) {
if base.scale == scale, let image = base.preparingForDisplay() {
Expand Down
6 changes: 3 additions & 3 deletions Sources/SwiftUI/KFAnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import SwiftUI
import Combine

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
public struct KFAnimatedImage: KFImageProtocol {
public typealias HoldingView = KFAnimatedImageViewRepresenter
public var context: Context<HoldingView>
Expand All @@ -48,7 +48,7 @@ public struct KFAnimatedImage: KFImageProtocol {
}

/// A wrapped `UIViewRepresentable` of `AnimatedImageView`
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
public struct KFAnimatedImageViewRepresenter: UIViewRepresentable, KFImageHoldingView {
public typealias RenderingView = AnimatedImageView
public static func created(from image: KFCrossPlatformImage?, context: KFImage.Context<Self>) -> KFAnimatedImageViewRepresenter {
Expand Down Expand Up @@ -77,7 +77,7 @@ public struct KFAnimatedImageViewRepresenter: UIViewRepresentable, KFImageHoldin
}

#if DEBUG
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
struct KFAnimatedImage_Previews: PreviewProvider {
static var previews: some View {
Group {
Expand Down
44 changes: 44 additions & 0 deletions Sources/SwiftUI/KFImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,53 @@
import SwiftUI
import Combine

/// Represents an image view in SwiftUI that manages its content using Kingfisher.
///
/// This view asynchronously loads the content. You can set a ``Source`` to load for the ``KFImage`` through
/// its ``KFImage/init(source:)`` or ``KFImage/init(_:)`` initializers or other relevant methods in ``KF`` Builder type.
/// Kingfisher will first look for the required image in the cache. If it is not found, it will load it via the
/// ``Source`` and provide the result for display, following sending the result to cache and for the future use.
///
/// When using a `URL` valve as the ``Source``, it is similar to SwiftUI's `AsyncImage` but with additional support
/// for caching.
///
/// Here is a basic example of using ``KFImage``:
///
/// ```swift
/// var body: some View {
/// KFImage(URL(string: "https://example.com/image.png")!)
/// }
/// ```
///
/// Usually, you can also use the value by calling additional modifiers defined on it, to configure the view:
///
/// ```swift
/// var body: some View {
/// KFImage.url(url)
/// .placeholder(placeholderImage)
/// .setProcessor(processor)
/// .loadDiskFileSynchronously()
/// .cacheMemoryOnly()
/// .onSuccess { result in }
/// }
/// ```
/// Here only very few are listed as demonstration. To check other available modifiers, see ``KFOptionSetter`` and its
/// extension methods.
///
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
public struct KFImage: KFImageProtocol {

/// Represent the wrapping context of the image view.
///
/// Inside ``KFImage`` it is using the `SwiftUI.Image` to render the image.
public var context: Context<Image>

/// Initializes the ``KFImage`` with a context.
///
/// This should be only used internally in Kingfisher. Do not use this initializer yourself. Instead, use
/// ``KFImage/init(source:)`` or ``KFImage/init(_:)`` initializers or other relevant methods in ``KF`` Builder
/// type.
/// - Parameter context: The context value that the image view should wrap.
public init(context: Context<Image>) {
self.context = context
}
Expand Down
Loading

0 comments on commit ba33e27

Please sign in to comment.