简体   繁体   English

如何从 url 设置 NSTextAttachment 图像?

[英]How to set a NSTextAttachment image from a url?

I am trying to set a NSTextAttachment image from a url, I tried to follow Coco.netics guide for Asynchronous NSTextAttachments but looks like it is not working.我正在尝试从 url 设置一个NSTextAttachment图像,我试图按照异步NSTextAttachments的 Coco.netics 指南进行操作,但看起来它不起作用。 My url works fine because I already downloaded things from it and teamLogo is not nil when I do the debug我的 url 工作正常,因为我已经从它下载了东西,并且在我进行调试时teamLogo不是nil

let teamLogo = Team.get()
let teamImage = team?.teamLogo
guard let image = teamImage else {return nil}

let teamImageAttachment = AsyncTextAttachment()

teamImageAttachment.imageURL = URL(string: image)
let stringWithTeamImage = NSAttributedString(attachment: teamImageAttachment)
let finalAttributedString = NSMutableAttributedString(string: "")
finalAttributedString.append(stringWithTeamImage)

since you use swift ,因为你使用swift

you can use the following KingFisher extension:您可以使用以下KingFisher扩展:

import Foundation
import UIKit


// MARK: - Associated Object
private var taskIdentifierK: Void?
private var placeholderK: Void?
private var imageTas_K: Void?

extension KingfisherWrapper where Base: NSTextAttachment {

    // MARK: Properties
    public private(set) var taskId: Source.Identifier.Value? {
        get {
            let box: Box<Source.Identifier.Value>? = getAssociatedObject(base, &taskIdentifierK)
            return box?.value
        }
        set {
            let box = newValue.map { Box($0) }
            setRetainedAssociatedObject(base, &taskIdentifierK, box)
        }
    }

    
    private var imageTask: DownloadTask? {
        get { return getAssociatedObject(base, &imageTas_K) }
        set { setRetainedAssociatedObject(base, &imageTas_K, newValue)}
    }

    /// Represents the `Placeholder` used for this image view. A `Placeholder` will be shown in the view while
    /// it is downloading an image.
    public private(set) var placeholder: UIImage? {
        get { return getAssociatedObject(base, &placeholderK) }
        set {
            if let previousPlaceholder = placeholder {
                base.image = nil
            }
            
            if let newPlaceholder = newValue {
                base.image = newPlaceholder
            } else {
                base.image = nil
            }
            setRetainedAssociatedObject(base, &placeholderK, newValue)
        }
    }
}





extension KingfisherWrapper where Base: NSTextAttachment {


    
    @discardableResult
    public func setImage(
        with resource: Resource?,
        placeholder: String,
        options: KingfisherOptionsInfo? = nil,
        progressBlock: DownloadProgressBlock? = nil,
        completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil) -> DownloadTask?
    {
        return setImage(
            with: resource?.convertToSource(),
            placeholder: UIImage(named: placeholder),
            options: options,
            progressBlock: progressBlock,
            completionHandler: completionHandler)
    }
    
    
    
    
    
    
    
    
    @discardableResult
    public func setImage(
        with source: Source?,
        placeholder: UIImage? = nil,
        options: KingfisherOptionsInfo? = nil,
        progressBlock: DownloadProgressBlock? = nil,
        completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil) -> DownloadTask?
    {
        let options = KingfisherParsedOptionsInfo(KingfisherManager.shared.defaultOptions + (options ?? []))
        return setImage(
            with: source,
            placeholder: placeholder,
            parsedOptions: options,
            progressBlock: progressBlock,
            completionHandler: completionHandler
        )
    }


    
    
    func setImage(
        with source: Source?,
        placeholder: UIImage? = nil,
        parsedOptions: KingfisherParsedOptionsInfo,
        progressBlock: DownloadProgressBlock? = nil,
        completionHandler: ((Result<RetrieveImageResult, KingfisherError>) -> Void)? = nil) -> DownloadTask?
    {
        var mutatingSelf = self
        guard let source = source else {
            /**
             * In iOS SDK 14.0-14.4 the image param was non-`nil`. The SDK changed in 14.5
             * to allow `nil`. The compiler version 5.4 was introduced in this same SDK,
             * which allows >=14.5 SDK to set a `nil` image. This compile check allows
             * newer SDK users to set the image to `nil`, while still allowing older SDK
             * users to compile the framework.
             */
            #if compiler(>=5.4)
            self.base.image = placeholder
            #else
            if let placeholder = placeholder {
                self.base.image = placeholder
            }
            #endif

            mutatingSelf.taskId = nil
            completionHandler?(.failure(KingfisherError.imageSettingError(reason: .emptySource)))
            return nil
        }
        
        var options = parsedOptions
        if !options.keepCurrentImageWhileLoading {
            /**
             * In iOS SDK 14.0-14.4 the image param was non-`nil`. The SDK changed in 14.5
             * to allow `nil`. The compiler version 5.4 was introduced in this same SDK,
             * which allows >=14.5 SDK to set a `nil` image. This compile check allows
             * newer SDK users to set the image to `nil`, while still allowing older SDK
             * users to compile the framework.
             */
            #if compiler(>=5.4)
            self.base.image = placeholder
            #else // Let older SDK users deal with the older behavior.
            if let placeholder = placeholder {
                self.base.image = placeholder
            }
            #endif
        }
        
        let issuedIdentifier = Source.Identifier.next()
        mutatingSelf.taskId = issuedIdentifier
        
        if let block = progressBlock {
            options.onDataReceived = (options.onDataReceived ?? []) + [ImageLoadingProgressSideEffect(block)]
        }
        
        if let provider = ImageProgressiveProvider(options, refresh: { image in
            self.base.image = image
        }) {
            options.onDataReceived = (options.onDataReceived ?? []) + [provider]
        }
        
        options.onDataReceived?.forEach {
            $0.onShouldApply = { issuedIdentifier == self.taskId }
        }
        
        let task = KingfisherManager.shared.retrieveImage(
            with: source,
            options: options,
            downloadTaskUpdated: { mutatingSelf.imageTask = $0 },
            completionHandler: { result in
                CallbackQueue.mainCurrentOrAsync.execute {
                    guard issuedIdentifier == self.taskId else {
                        let reason: KingfisherError.ImageSettingErrorReason
                        do {
                            let value = try result.get()
                            reason = .notCurrentSourceTask(result: value, error: nil, source: source)
                        } catch {
                            reason = .notCurrentSourceTask(result: nil, error: error, source: source)
                        }
                        let error = KingfisherError.imageSettingError(reason: reason)
                        completionHandler?(.failure(error))
                        return
                    }
                    
                    mutatingSelf.imageTask = nil
                    mutatingSelf.taskId = nil
                    
                    switch result {
                        case .success(let value):
                            self.base.image = value.image
                            completionHandler?(result)
                            
                        case .failure:
                            if let image = options.onFailureImage {
                                /**
                                 * In iOS SDK 14.0-14.4 the image param was non-`nil`. The SDK changed in 14.5
                                 * to allow `nil`. The compiler version 5.4 was introduced in this same SDK,
                                 * which allows >=14.5 SDK to set a `nil` image. This compile check allows
                                 * newer SDK users to set the image to `nil`, while still allowing older SDK
                                 * users to compile the framework.
                                 */
                                #if compiler(>=5.4)
                                self.base.image = image
                                #else // Let older SDK users deal with the older behavior.
                                if let unwrapped = image {
                                    self.base.image = unwrapped
                                }
                                #endif
                                
                            } else {
                                #if compiler(>=5.4)
                                self.base.image = nil
                                #endif
                            }
                            completionHandler?(result)
                    }
                }
            }
        )
        
        mutatingSelf.imageTask = task
        return task
    }
}

call like this,像这样打电话,

    let attriString = NSMutableAttributedString()
    let attachment = NSTextAttachment()
    let edge: CGFloat = 30
    let y = (txtFont.capHeight - edge) * 0.5
    attachment.bounds = CGRect(x: 0, y: y, width: edge, height: edge)
    attachment.kf.setImage(with: URL(string: ddd.gift.avatar), placeholder: "hl_gift_display_default", completionHandler:{ result in
        switch result{
        case .success:
            self.label.setNeedsDisplay()
        case .failure: ()
        }
    })
    let attachmentString = NSAttributedString(attachment: attachment)
    attriString?.append(attachmentString)
    label.attributedText = attriString
teamImageAttachment.imageURL = URL(string: image)

after the image is downloaded,下载image后,

you shall refresh the label ,你应该刷新label

which label.attributedText其中label.attributedText


by经过

label.setNeedsDisplay()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM