Skip to content

Commit

Permalink
Merge pull request #53 from RakuyoKit/feature/three-theme-color
Browse files Browse the repository at this point in the history
Feature/three-theme-color
  • Loading branch information
rakuyoMo authored Jul 4, 2024
2 parents 374aa45 + 762b45b commit 570ed89
Show file tree
Hide file tree
Showing 23 changed files with 138 additions and 135 deletions.
10 changes: 5 additions & 5 deletions Sources/Combine/Core/DelegateProxy/DelegateProxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,30 @@ import Combine
open class DelegateProxy: ObjcDelegateProxy {
private var dict: [Selector: [([Any]) -> Void]] = [:]
private var subscribers = [AnySubscriber<[Any], Never>?]()

override public required init() {
super.init()
}

deinit {
for subscriber in subscribers { subscriber?.receive(completion: .finished) }
subscribers = []
}

override public func interceptedSelector(_ selector: Selector, arguments: [Any]) {
dict[selector]?.forEach { handler in
handler(arguments)
}
}

public func intercept(_ selector: Selector, _ handler: @escaping ([Any]) -> Void) {
if dict[selector] != nil {
dict[selector]?.append(handler)
} else {
dict[selector] = [handler]
}
}

public func interceptSelectorPublisher(_ selector: Selector) -> AnyPublisher<[Any], Never> {
DelegateProxyPublisher<[Any]> { subscriber in
self.subscribers.append(subscriber)
Expand Down
12 changes: 6 additions & 6 deletions Sources/Combine/Core/DelegateProxy/DelegateProxyPublisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import Combine
@available(iOS 13.0, *)
final class DelegateProxyPublisher<Output>: Publisher {
typealias Failure = Never

private let handler: (AnySubscriber<Output, Failure>) -> Void

init(_ handler: @escaping (AnySubscriber<Output, Failure>) -> Void) {
self.handler = handler
}

func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
let subscription = Subscription(subscriber: AnySubscriber(subscriber), handler: handler)
subscriber.receive(subscription: subscription)
Expand All @@ -23,16 +23,16 @@ final class DelegateProxyPublisher<Output>: Publisher {
extension DelegateProxyPublisher {
fileprivate class Subscription<S>: Combine.Subscription where S: Subscriber, Failure == S.Failure, Output == S.Input {
private var subscriber: S?

init(subscriber: S, handler: @escaping (S) -> Void) {
self.subscriber = subscriber
handler(subscriber)
}

func request(_: Subscribers.Demand) {
// We don't care for the demand.
}

func cancel() {
subscriber = nil
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/Combine/Core/DelegateProxy/DelegateProxyType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ private var associatedKey: Void?

public protocol DelegateProxyType {
associatedtype Object

func setDelegate(to object: Object)
}

Expand All @@ -14,9 +14,9 @@ extension DelegateProxyType where Self: DelegateProxy {
public static func createDelegateProxy(for object: Object) -> Self {
objc_sync_enter(self)
defer { objc_sync_exit(self) }

let delegateProxy: Self

if let associatedObject = objc_getAssociatedObject(object, &associatedKey) as? Self {
delegateProxy = associatedObject
} else {
Expand All @@ -25,7 +25,7 @@ extension DelegateProxyType where Self: DelegateProxy {
}

delegateProxy.setDelegate(to: object)

return delegateProxy
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Combine/Core/Extendable/AnyPublisher+SAK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ extension AnyPublisher {
public static func empty(completeImmediately: Bool = true) -> Self {
Empty<Self.Output, Self.Failure>(completeImmediately: completeImmediately).eraseToAnyPublisher()
}

/// 直接发送一个信号
public static func send(value: Self.Output) -> Self {
Result<Self.Output, Self.Failure>.Publisher(.success(value)).eraseToAnyPublisher()
Expand Down
6 changes: 3 additions & 3 deletions Sources/Combine/Core/Extendable/NSTextStorage+Combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ extension Extendable where Base: NSTextStorage {
editedRange: NSRange,
delta: Int
)

/// Combine publisher for `NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:)`
public var didProcessEditingRangeChangeInLengthPublisher: AnyPublisher< // swiftlint:disable:this identifier_name
ProcessEditingRangeChangeOutput,
Never
> {
let selector = #selector(NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:))

return delegateProxy
.interceptSelectorPublisher(selector)
.map { args -> (editedMask: NSTextStorage.EditActions, editedRange: NSRange, delta: Int) in
Expand All @@ -31,7 +31,7 @@ extension Extendable where Base: NSTextStorage {
}
.eraseToAnyPublisher()
}

private var delegateProxy: NSTextStorageDelegateProxy {
.createDelegateProxy(for: base)
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Combine/Core/Extendable/Publisher+UITextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ extension Publisher where Self.Output: UITextField {
public func limitInputLength(max: Int?) -> Publishers.Map<Self, String> {
map {
var content = $0.text ?? ""

if let max, content.rak.length > max {
content = content.rak.prefixed(max)
$0.text = content
}

return content
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension Publishers {
guard let first = array.first else {
return Empty().eraseToAnyPublisher()
}

return array
.dropFirst()
.reduce(
Expand Down
10 changes: 5 additions & 5 deletions Sources/Combine/Core/Extendable/UITextView+Combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ extension Extendable where Base: UITextView {
}
.eraseToAnyPublisher()
}

/// Combine wrapper for `textViewDidBeginEditing(_:)`
public var didBeginEditingPublisher: AnyPublisher<Void, Never> {
let selector = #selector(UITextViewDelegate.textViewDidBeginEditing(_:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { _ in }
.eraseToAnyPublisher()
}

/// Combine wrapper for `textViewDidEndEditing(_:)`
public var didEndEditingPublisher: AnyPublisher<Void, Never> {
let selector = #selector(UITextViewDelegate.textViewDidEndEditing(_:))
return delegateProxy.interceptSelectorPublisher(selector)
.map { _ in }
.eraseToAnyPublisher()
}

/// A publisher emits on first responder changes
public var isFirstResponderPublisher: AnyPublisher<Bool, Never> {
Just<Void>(())
Expand All @@ -48,7 +48,7 @@ extension Extendable where Base: UITextView {
}
.eraseToAnyPublisher()
}

/// A publisher emits on selected range changes
public var selectedRangePublisher: AnyPublisher<NSRange, Never> {
let selector = #selector(UITextViewDelegate.textViewDidChangeSelection(_:))
Expand All @@ -58,7 +58,7 @@ extension Extendable where Base: UITextView {
}
.eraseToAnyPublisher()
}

private var delegateProxy: DelegateProxy {
TextViewDelegateProxy.createDelegateProxy(for: base)
}
Expand Down
16 changes: 8 additions & 8 deletions Sources/Combine/Core/Keyboard/KeyboardChangeContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ import UIKit
/// The context of an upcoming change in the frame of the system keyboard.
public struct _KeyboardChangeContext {
// swiftlint:enable type_name

private let base: [AnyHashable: Any]

/// The event type of the system keyboard.
public let event: KeyboardEvent

/// The current frame of the system keyboard.
public var beginFrame: CGRect {
// swiftlint:disable:next force_cast
base[UIResponder.keyboardFrameBeginUserInfoKey] as! CGRect
}

/// The final frame of the system keyboard.
public var endFrame: CGRect {
// swiftlint:disable:next force_cast
base[UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
}

/// The animation curve which the system keyboard will use to animate the
/// change in its frame.
public var animationCurve: UIView.AnimationCurve {
Expand All @@ -32,14 +32,14 @@ public struct _KeyboardChangeContext {
return UIView.AnimationCurve(rawValue: value.intValue)!
// swiftlint:enable force_unwrapping
}

/// The duration in which the system keyboard expects to animate the change in
/// its frame.
public var animationDuration: Double {
// swiftlint:disable:next force_cast
base[UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
}

/// Indicates whether the change is triggered locally. Used in iPad
/// multitasking, where all foreground apps would be notified of any changes
/// in the system keyboard's frame.
Expand All @@ -48,7 +48,7 @@ public struct _KeyboardChangeContext {
// swiftlint:disable:next force_cast
base[UIResponder.keyboardIsLocalUserInfoKey] as! Bool
}

init(userInfo: [AnyHashable: Any], event: KeyboardEvent) {
base = userInfo
self.event = event
Expand Down
2 changes: 1 addition & 1 deletion Sources/Combine/Core/Keyboard/KeyboardEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public enum KeyboardEvent {
case willChangeFrame
case didChangeFrame
// swiftlint:enable sorted_enum_cases

/// The name of the notification to observe system keyboard events.
var notificationName: Notification.Name {
switch self {
Expand Down
16 changes: 8 additions & 8 deletions Sources/Combine/Core/Keyboard/KeyboardListenable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import Combine
public protocol KeyboardListenable: NSObjectProtocol {
// swiftlint:disable:next implicitly_unwrapped_optional
var view: UIView! { get set }

/// 适用于列表
var listView: UIScrollView? { get }

/// 可取消的绑定
var cancellable: Set<AnyCancellable> { get set }

#if !os(tvOS)
/// 键盘监听之后的逻辑
func keyboardChange(_ context: _KeyboardChangeContext)
Expand All @@ -23,7 +23,7 @@ public protocol KeyboardListenable: NSObjectProtocol {

extension KeyboardListenable {
public var listView: UIScrollView? { nil }

#if !os(tvOS)
@available(iOSApplicationExtension, unavailable, message: "This method is NS_EXTENSION_UNAVAILABLE.")
public func keyboardChange(_ context: _KeyboardChangeContext) {
Expand All @@ -43,22 +43,22 @@ extension KeyboardListenable {
.sink { [weak self] in (handle ?? self?.keyboardChange)?($0) }
.store(in: &cancellable)
}

/// 键盘监听事件的默认行为
@available(iOSApplicationExtension, unavailable, message: "This method is NS_EXTENSION_UNAVAILABLE.")
public func defaultKeyboardChangeBehavior(_ context: _KeyboardChangeContext) {
// visionOS 应该不需要处理键盘弹起
#if !os(visionOS)
guard let _listView = listView else { return }

let height = UIApplication.shared.rak.statusBarHeight(in: view) + 44

if context.endFrame.minY != UIScreen.rak.mainBounds.height {
// 弹
let bottom = context.endFrame.height - height
_listView.contentInset = .init(top: 0, left: 0, bottom: bottom, right: 0)
_listView.scrollIndicatorInsets = .init(top: 0, left: 0, bottom: bottom, right: 0)

} else {
// 收
_listView.contentInset = .zero
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import RAKCore

extension Extendable where Base: NotificationCenter {
public typealias KeyboardPublisher = AnyPublisher<_KeyboardChangeContext, Never>

public var keyboardChange: KeyboardPublisher {
keyboard(.willChangeFrame)
.removeDuplicates { $0.endFrame == $1.endFrame }
.eraseToAnyPublisher()
}

public func keyboard(_ event: KeyboardEvent) -> KeyboardPublisher {
NotificationCenter.default
.publisher(for: event.notificationName)
Expand Down
16 changes: 8 additions & 8 deletions Sources/Combine/Core/ObservableProperty/BindableProperty.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public final class BindableProperty<Value>: BindableConvertibleProperty<Value, V
public init(_ value: Value) {
super.init(value, map: nil)
}

@available(*, unavailable)
override init(_: Value, map _: ObservableMapBlock?) {
fatalError("init(_:map:) has not been implemented")
Expand All @@ -21,25 +21,25 @@ public final class BindableProperty<Value>: BindableConvertibleProperty<Value, V
///
public class BindableConvertibleProperty<Value, Convert> {
public typealias Wrapper = ObservablePropertyWrapper<Value, Convert>

public typealias ObservableMapBlock = Wrapper.ObservableMapBlock

public var value: Value { observableWrapper.value }

public var valuePublisher: AnyPublisher<Value, Never> {
observableWrapper.valuePublisher
}

public var valueMapPublisher: AnyPublisher<Convert, Never> {
observableWrapper.valueMapPublisher
}

private let observableWrapper: Wrapper

public init(_ value: Value, map: ObservableMapBlock?) {
observableWrapper = .init(value, map: map)
}

public func update(_ value: Value) {
observableWrapper.update(value)
}
Expand Down
Loading

0 comments on commit 570ed89

Please sign in to comment.