Skip to content

Commit

Permalink
[macOS] addtional control to the back NSView by a closure.
Browse files Browse the repository at this point in the history
  • Loading branch information
mobilinked committed Dec 24, 2020
1 parent 639bfcc commit 3be2ecc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
8 changes: 4 additions & 4 deletions Sources/MbSwiftUIFirstResponder/Mac/Interface - mac.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
import SwiftUI

extension TextField {
public func firstResponder<V: Hashable>(id: V, firstResponder: Binding<V?>, resignableUserOperations: MbFirstResponder.TextField.ResignableUserOperations = .all) -> some View {
public func firstResponder<V: Hashable>(id: V, firstResponder: Binding<V?>, resignableUserOperations: MbFirstResponder.TextField.ResignableUserOperations = .all, didBackViewLoaded: ((NSTextField) -> Void)? = nil) -> some View {
self
.background(MbFRHackView<V, NSTextField>(id: id, firstResponder: firstResponder, resignableUserOperations: resignableUserOperations))
.background(MbFRHackView<V, NSTextField>(id: id, firstResponder: firstResponder, resignableUserOperations: resignableUserOperations, didBackViewLoaded: didBackViewLoaded))
}
}

extension TextEditor {
public func firstResponder<V: Hashable>(id: V, firstResponder: Binding<V?>, resignableUserOperations: MbFirstResponder.TextEditor.ResignableUserOperations = .all) -> some View {
public func firstResponder<V: Hashable>(id: V, firstResponder: Binding<V?>, resignableUserOperations: MbFirstResponder.TextEditor.ResignableUserOperations = .all, didBackViewLoaded: ((NSTextView) -> Void)? = nil) -> some View {
self
.background(MbFRHackView<V, NSTextView>(id: id, firstResponder: firstResponder, resignableUserOperations: resignableUserOperations))
.background(MbFRHackView<V, NSTextView>(id: id, firstResponder: firstResponder, resignableUserOperations: resignableUserOperations, didBackViewLoaded: didBackViewLoaded))
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,36 @@ struct MbFRHackView<ID: Hashable, Field: FirstResponderableField>: NSViewReprese
// }

private let resignableUserOperations: Field.ResignableUserOperations
private let didBackViewLoaded: ((Field) -> Void)?

init(id: ID, firstResponder: Binding<ID?>, resignableUserOperations: Field.ResignableUserOperations) {
init(id: ID, firstResponder: Binding<ID?>, resignableUserOperations: Field.ResignableUserOperations, didBackViewLoaded: ((Field) -> Void)?) {
// print("init")
self.id = id
self._firstResponder = firstResponder
self.resignableUserOperations = resignableUserOperations
self.didBackViewLoaded = didBackViewLoaded
}

func makeNSView(context: Context) -> MbFRHackNSView<Field> {
// print("makeNSView")
return MbFRHackNSView(
isFirstResponder: id == firstResponder,
eventsAllowedToResignFirstResponder: resignableUserOperations) { focused in
// change the binding value after the first responder status changed by windows event (NOT changed programmaly)
if focused {
if firstResponder != id {
firstResponder = id
eventsAllowedToResignFirstResponder: resignableUserOperations,
firstResponderDidChangedByEvent: { focused in
// change the binding value after the first responder status changed by windows event (NOT changed programmaly)
if focused {
if firstResponder != id {
firstResponder = id
}
}
}
else {
if firstResponder == id {
firstResponder = nil
else {
if firstResponder == id {
firstResponder = nil
}
}
}
}
},
didBackViewLoaded: didBackViewLoaded
)
}

func updateNSView(_ nsView: MbFRHackNSView<Field>, context: Context) {
Expand All @@ -56,6 +61,7 @@ final class MbFRHackNSView<Field: FirstResponderableField>: NSView, FrEventObser
private weak var field: Field? = nil
private let initialFirstResponderStatus: Bool
private var resignableUserOperations: Field.ResignableUserOperations
private let didBackViewLoaded: ((Field) -> Void)?

// use the monitor if the first responder changed by the window event (NOT changed programmaly)
// for example, click outside the field, the text field will resign the first responder
Expand All @@ -65,10 +71,12 @@ final class MbFRHackNSView<Field: FirstResponderableField>: NSView, FrEventObser
init(
isFirstResponder: Bool,
eventsAllowedToResignFirstResponder: Field.ResignableUserOperations,
firstResponderDidChangedByEvent: @escaping (Bool) -> Void) {
firstResponderDidChangedByEvent: @escaping (Bool) -> Void,
didBackViewLoaded: ((Field) -> Void)?) {
self.initialFirstResponderStatus = isFirstResponder
self.resignableUserOperations = eventsAllowedToResignFirstResponder
self.firstResponderDidChangedByEvent = firstResponderDidChangedByEvent
self.didBackViewLoaded = didBackViewLoaded
super.init(frame: .zero)
self.wantsLayer = true
}
Expand All @@ -95,6 +103,7 @@ final class MbFRHackNSView<Field: FirstResponderableField>: NSView, FrEventObser

guard let window = self.window else { return }
if let tf = self.field {
self.didBackViewLoaded?(tf)
self.trackRelatedEvents(in: window)

let initialFirstResponder = self.initialFirstResponderStatus
Expand Down

0 comments on commit 3be2ecc

Please sign in to comment.