122 lines
3.2 KiB
Swift
122 lines
3.2 KiB
Swift
//
|
|
// AvatarImageView.swift
|
|
// Mastodon
|
|
//
|
|
// Created by MainasuK Cirno on 2021-7-21.
|
|
//
|
|
|
|
import UIKit
|
|
import FLAnimatedImage
|
|
import AlamofireImage
|
|
|
|
public class AvatarImageView: FLAnimatedImageView {
|
|
public var imageViewSize: CGSize?
|
|
public var url: URL? = nil
|
|
public var cornerConfiguration = CornerConfiguration()
|
|
}
|
|
|
|
extension AvatarImageView {
|
|
|
|
public func prepareForReuse() {
|
|
cancelTask()
|
|
af.cancelImageRequest()
|
|
}
|
|
|
|
override public func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
setup(corner: cornerConfiguration.corner)
|
|
}
|
|
|
|
private func setup(corner: CornerConfiguration.Corner) {
|
|
layer.masksToBounds = true
|
|
switch corner {
|
|
case .circle:
|
|
layer.cornerCurve = .circular
|
|
layer.cornerRadius = frame.width / 2
|
|
case .fixed(let radius):
|
|
layer.cornerCurve = .continuous
|
|
layer.cornerRadius = radius
|
|
case .scale(let ratio):
|
|
let radius = CGFloat(Int(bounds.width) / ratio) // even number from quoter of width
|
|
layer.cornerCurve = .continuous
|
|
layer.cornerRadius = radius
|
|
}
|
|
}
|
|
|
|
private func setup(border: CornerConfiguration.Border?) {
|
|
layer.borderColor = border?.color.cgColor
|
|
layer.borderWidth = border?.width ?? .zero
|
|
}
|
|
|
|
}
|
|
|
|
extension AvatarImageView {
|
|
|
|
public static let placeholder = UIImage.placeholder(color: .systemFill)
|
|
|
|
public func configure(with url: URL?) {
|
|
prepareForReuse()
|
|
|
|
self.url = url
|
|
|
|
guard let url else { return }
|
|
|
|
switch url.pathExtension.lowercased() {
|
|
case "gif":
|
|
setImage(
|
|
url: url,
|
|
scaleToSize: imageViewSize
|
|
)
|
|
default:
|
|
let filter: ImageFilter? = {
|
|
if let imageViewSize = self.imageViewSize {
|
|
return ScaledToSizeFilter(size: imageViewSize)
|
|
}
|
|
guard self.frame.size.width != 0,
|
|
self.frame.size.height != 0
|
|
else { return nil }
|
|
return ScaledToSizeFilter(size: self.frame.size)
|
|
}()
|
|
|
|
af.setImage(
|
|
withURL: url,
|
|
filter: filter
|
|
)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extension AvatarImageView {
|
|
public struct CornerConfiguration {
|
|
public let corner: Corner
|
|
public let border: Border?
|
|
|
|
public init(
|
|
corner: Corner = .circle,
|
|
border: Border? = nil
|
|
) {
|
|
self.corner = corner
|
|
self.border = border
|
|
}
|
|
|
|
public enum Corner {
|
|
case circle
|
|
case fixed(radius: CGFloat)
|
|
case scale(ratio: Int = 4) // width / ratio
|
|
}
|
|
|
|
public struct Border {
|
|
public let color: UIColor
|
|
public let width: CGFloat
|
|
}
|
|
}
|
|
|
|
public func configure(cornerConfiguration: CornerConfiguration) {
|
|
self.cornerConfiguration = cornerConfiguration
|
|
setup(corner: cornerConfiguration.corner)
|
|
setup(border: cornerConfiguration.border)
|
|
}
|
|
}
|