问题描述
列表元素:
struct PaletteListRowUIView: View {
@State var colorPalette: ColorPalette
var isSelected: Bool
var onSelect: () -> Void
var body: some View {
return vstack(alignment: .leading) {
HStack {
Group {
if(isSelected) {
Ellipse().fill(Color.white)
} else {
Ellipse().stroke(Color.white)
}
}.contentShape(Ellipse())
.aspectRatio(1,contentMode: .fit).frame(width: 10,height: 10)
.gesture(TapGesture().onEnded(onSelect))
RenameableText(text: $colorPalette.name,onFinished: {/* saves to core data */})
}
}
}
}
列表本身:
struct PaletteListUIView: View {
@EnvironmentObject var colorPaletteManager: ColorPaletteManager
var body: some View {
List {
ForEach(Array(self.colorPaletteManager.colorPalettes.enumerated()),id: \.element.id) { idx,palette in
PaletteListRowUIView(
colorPalette: palette,isSelected: self.colorPaletteManager.isSelected(index: idx),onSelect: { self.colorPaletteManager.selectPalette(at: idx) })
}.frame(height: 50)
}.frame(width: 256)
}
}
还有一个包装好的NSTextField:
class RenameableTextController: NSViewController {
@Binding var text: String
let onFinished: () -> Void
var originalValue: String?
var isInEditMode: Bool = false
private var monitors: [Any?] = []
private var tapper: NSClickGestureRecognizer?
init(text: Binding<String>,onFinished: @escaping () -> Void) {
self._text = text
self.onFinished = onFinished
super.init(nibName: nil,bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
let textField = NSTextField()
textField.cell = CustomTextFieldCell()
textField.stringValue = text
textField.isEditable = false
textField.isBordered = false
textField.bezelStyle = .roundedBezel
textField.backgroundColor = .clear
self.view = textField
}
override func viewWilldisappear() {
self.makeTextFieldInEditable()
}
override func mouseUp(with event: NSEvent) {
print("double")
if(event.clickCount == 2) {
self.makeTextFieldEditable()
}
}
func makeTextFieldEditable() {
self.isInEditMode = true
let textField = self.view as! NSTextField
self.originalValue = textField.stringValue
textField.delegate = self
textField.isEditable = true
textField.isBordered = true
self.view.window?.makeFirstResponder(textField)
textField.currentEditor()?.selectedRange = .init(location: textField.stringValue.count,length: 0)
monitorForEvents()
}
func makeTextFieldInEditable() {
let textField = self.view as! NSTextField
textField.resignFirstResponder()
if(isInEditMode) { // This line is necessary because otherwise a depencency cycle is created in SwiftUI
self.view.window?.makeFirstResponder(nil)
}
textField.isEditable = false
textField.isBordered = false
removeMonitors()
self.isInEditMode = false
}
override func cancelOperation(_ sender: Any?) {
let textField = self.view as! NSTextField
textField.stringValue = originalValue!
makeTextFieldInEditable()
}
}
extension RenameableTextController: NSTextFieldDelegate {
func controlTextDidChange(_ obj: Notification) {
if let textField = obj.object as? NSTextField {
self.text = textField.stringValue
}
}
func controlTextDidEndEditing(_ obj: Notification) {
makeTextFieldInEditable()
onFinished()
}
}
extension RenameableTextController {
func monitorForEvents() {
let localMonitor = NSEvent.addLocalMonitorForEvents(matching: [.leftMouseUp]) { event in
self.makeTextFieldInEditable()
return event
}
monitors.append(localMonitor)
}
func removeMonitors() {
monitors.forEach { monitor in
if let monitor = monitor {
NSEvent.removeMonitor(monitor)
}
}
monitors = []
}
}
struct RenameableText: NSViewControllerRepresentable {
@Binding var text: String
let onFinished: () -> Void
func makeNSViewController(
context: NSViewControllerRepresentableContext<RenameableText>
) -> RenameableTextController {print("called")
return RenameableTextController(text: $text,onFinished: onFinished)
}
func updateNSViewController(
_ nsViewController: RenameableTextController,context: NSViewControllerRepresentableContext<RenameableText>
) {
}
}
我使用RenameableText
以便通过双击在列表中重命名该条目。 但是仅当您将List
替换为vstack
时,此功能才能正常工作。一旦我使用List
SwiftUI View,NSViewControllerRepresentable
就不再收到mouseUp
事件。有趣的是,包含Group
的{{1}}视图仍在响应TapGesture()。
有人经历过类似的行为并且知道如何解决这个问题,或者这是应该报告的错误吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)