Skip to content

Commit

Permalink
Merge pull request #39 from mykyta-rusyn/feat/activity-indicator-color
Browse files Browse the repository at this point in the history
feat: changing activity color for iOS
  • Loading branch information
gtokman committed Jun 1, 2024
2 parents 3ab5a1b + ff7af44 commit 17435bf
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ await clearCache();
| resizeMode | string | contain | The resize mode of the image |
| thumbhash | string | | The thumbhash of the image as a base64 encoded string to show while loading (Android not tested) |
| blurhash | string | | The blurhash of the image to show while loading (iOS only) |
| showActivityIndicator | boolean | false (iOS only) | Whether to show the UIActivityIndicatorView indicator when the image is loading |
| showActivityIndicator | boolean | false (iOS only) | Whether to show the UIActivityIndicatorView indicator when the image is loading
| activityColor | ColorValue | undefined (iOS only) | Activity indicator color. Changed default activity indicator color. Only hex supported |
| base64Placeholder | string | | The base64 encoded placeholder image to show while the image is loading |
| cachePolicy | string | memory | The cache policy of the image |
| transitionDuration | number | 0.75 (iOS) Android (100) | The transition duration of the image |
Expand Down
66 changes: 65 additions & 1 deletion ios/FasterImageViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct ImageOptions: Decodable {
let thumbhash: String?
let resizeMode: String?
let showActivityIndicator: Bool?
let activityColor: String?
let transitionDuration: Double?
let cachePolicy: String?
let failureImage: String?
Expand Down Expand Up @@ -120,6 +121,9 @@ final class FasterImageView: UIView {
self.thumbhash = thumbhash
}
resizeMode = options.resizeMode ?? "contain"
if let activityColor = options.activityColor {
self.activityColor = UIColor(hex: activityColor)
}
if let showActivityIndicator = options.showActivityIndicator {
self.showActivityIndicator = showActivityIndicator
}
Expand Down Expand Up @@ -231,10 +235,16 @@ final class FasterImageView: UIView {

var showActivityIndicator = false {
didSet {
lazyImageView.placeholderView = UIActivityIndicatorView()
let activity = UIActivityIndicatorView()
if self.activityColor != nil {
activity.color = self.activityColor
}
lazyImageView.placeholderView = activity
}
}

var activityColor: UIColor?

var resizeMode = "contain" {
didSet {
let mode = ResizeMode(rawValue: resizeMode)
Expand Down Expand Up @@ -365,3 +375,57 @@ fileprivate extension FasterImageView {
}

}

fileprivate extension UIColor {
convenience init?(hex: String) {
if !hex.starts(with: "#") {
return nil
}

let input = hex
.replacingOccurrences(of: "#", with: "")
.uppercased()
var alpha: CGFloat = 1.0
var red: CGFloat = 0
var blue: CGFloat = 0
var green: CGFloat = 0

switch (input.count) {
case 3 /* #RGB */:
red = Self.colorComponent(from: input, start: 0, length: 1)
green = Self.colorComponent(from: input, start: 1, length: 1)
blue = Self.colorComponent(from: input, start: 2, length: 1)
break
case 4 /* #ARGB */:
alpha = Self.colorComponent(from: input, start: 0, length: 1)
red = Self.colorComponent(from: input, start: 1, length: 1)
green = Self.colorComponent(from: input, start: 2, length: 1)
blue = Self.colorComponent(from: input, start: 3, length: 1)
break
case 6 /* #RRGGBB */:
red = Self.colorComponent(from: input, start: 0, length: 2)
green = Self.colorComponent(from: input, start: 2, length: 2)
blue = Self.colorComponent(from: input, start: 4, length: 2)
break
case 8 /* #AARRGGBB */:
alpha = Self.colorComponent(from: input, start: 0, length: 2)
red = Self.colorComponent(from: input, start: 2, length: 2)
green = Self.colorComponent(from: input, start: 4, length: 2)
blue = Self.colorComponent(from: input, start: 6, length: 2)
break
default:
return nil
}
self.init(red: red, green: green, blue: blue, alpha: alpha)
}

static func colorComponent(from: String, start: Int, length: Int) -> CGFloat {
let substring = (from as NSString)
.substring(with: NSRange(location: start, length: length))
let fullHex = length == 2 ? substring : "\(substring)\(substring)"
var hexComponent: UInt64 = 0
Scanner(string: fullHex)
.scanHexInt64(&hexComponent)
return CGFloat(Double(hexComponent) / 255.0)
}
}
3 changes: 3 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
requireNativeComponent,
NativeModules,
Platform,
ColorValue,
} from 'react-native';

export type IOSImageResizeMode =
Expand Down Expand Up @@ -34,6 +35,7 @@ export type AndroidImageResizeMode =
* @property {string} [thumbhash] - Thumbhash of the image (base64 encoded) (iOS only)
* @property {('cover' | 'contain' | 'center' | 'fill')} [resizeMode] - Resize mode of the image
* @property {boolean} [showActivityIndicator] - Show activity indicator while loading, overrides placeholder. Defaults to false (iOS only)
* @property {ColorValue} [activityColor] - Activity indicator color. Changed default activity indicator color if specified. Defaults to undefined (iOS only)
* @property {number} [transitionDuration] - Duration of the transition animation in seconds, defaults to 0.75
* @property {string} [failureImage] - Image to show when the image fails to load, pass blurhash, thumbhash or base64 encoded image
* @property {boolean} [progressiveLoadingEnabled] - Enable progressive loading, defaults to false
Expand All @@ -58,6 +60,7 @@ export type ImageOptions = {
borderBottomLeftRadius?: number;
borderBottomRightRadius?: number;
showActivityIndicator?: boolean;
activityColor?: ColorValue;
transitionDuration?: number;
cachePolicy?: 'memory' | 'discWithCacheControl' | 'discNoCacheControl';
failureImage?: string;
Expand Down

0 comments on commit 17435bf

Please sign in to comment.