Signal-iOS/SignalUI/Views/ConversationView/CVUtils.swift
2021-10-19 09:39:53 -03:00

149 lines
3.3 KiB
Swift

//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
import Foundation
import YYImage
public class CVUtils {
@available(*, unavailable, message: "use other init() instead.")
private init() {}
private static let workQueue_userInitiated: DispatchQueue = {
DispatchQueue(label: "org.whispersystems.signal.conversationView.workQueue_userInitiated",
qos: .userInitiated,
autoreleaseFrequency: .workItem)
}()
private static let workQueue_userInteractive: DispatchQueue = {
DispatchQueue(label: "org.whispersystems.signal.conversationView.workQueue_userInteractive",
qos: .userInteractive,
autoreleaseFrequency: .workItem)
}()
public static func workQueue(isInitialLoad: Bool) -> DispatchQueue {
isInitialLoad ? workQueue_userInteractive : workQueue_userInitiated
}
public static let landingQueue: DispatchQueue = {
DispatchQueue(label: "org.whispersystems.signal.conversationView.landingQueue",
qos: .userInitiated,
autoreleaseFrequency: .workItem)
}()
}
// MARK: -
public protocol CVView: UIView {
func reset()
}
// MARK: -
@objc
open class CVLabel: UILabel, CVView {
public override func updateConstraints() {
super.updateConstraints()
deactivateAllConstraints()
}
public func reset() {
self.text = nil
}
}
// MARK: -
@objc
open class CVImageView: UIImageView, CVView {
public override func updateConstraints() {
super.updateConstraints()
deactivateAllConstraints()
}
public func reset() {
self.image = nil
}
// MARK: - Layout
public typealias LayoutBlock = (UIView) -> Void
private var layoutBlocks = [LayoutBlock]()
public func addLayoutBlock(_ layoutBlock: @escaping LayoutBlock) {
layoutBlocks.append(layoutBlock)
}
public override var bounds: CGRect {
didSet {
if oldValue.size != bounds.size {
viewSizeDidChange()
}
}
}
public override var frame: CGRect {
didSet {
if oldValue.size != frame.size {
viewSizeDidChange()
}
}
}
func viewSizeDidChange() {
layoutSubviews()
}
open override func layoutSubviews() {
layoutSubviews(skipLayoutBlocks: false)
}
public func layoutSubviews(skipLayoutBlocks: Bool = false) {
AssertIsOnMainThread()
super.layoutSubviews()
if !skipLayoutBlocks {
applyLayoutBlocks()
}
}
public func applyLayoutBlocks() {
AssertIsOnMainThread()
for layoutBlock in layoutBlocks {
layoutBlock(self)
}
}
// MARK: - Circles
@objc
public static func circleView() -> CVImageView {
let result = CVImageView()
result.addLayoutBlock { view in
view.layer.cornerRadius = min(view.width, view.height) * 0.5
}
return result
}
}
// MARK: -
@objc
open class CVAnimatedImageView: YYAnimatedImageView, CVView {
public override func updateConstraints() {
super.updateConstraints()
deactivateAllConstraints()
}
public func reset() {
self.image = nil
}
}