diff --git a/AirPush.xcodeproj/project.pbxproj b/AirPush.xcodeproj/project.pbxproj index 27ea064..561a2ab 100644 --- a/AirPush.xcodeproj/project.pbxproj +++ b/AirPush.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 0156FD4E2498A18E003909E9 /* PushViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0156FD4D2498A18E003909E9 /* PushViewModel.swift */; }; 0156FD562498F941003909E9 /* Chain in Frameworks */ = {isa = PBXBuildFile; productRef = 0156FD552498F941003909E9 /* Chain */; }; 016B434B249C9CEB0077D50D /* BoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016B434A249C9CEB0077D50D /* BoxView.swift */; }; + 01C356B124B5C062007A42F2 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C356B024B5C062007A42F2 /* TextView.swift */; }; 01DFAB8A248CD21B003664BE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DFAB89248CD21B003664BE /* AppDelegate.swift */; }; 01DFAB8C248CD21B003664BE /* PushView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DFAB8B248CD21B003664BE /* PushView.swift */; }; 01DFAB8E248CD21B003664BE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 01DFAB8D248CD21B003664BE /* Assets.xcassets */; }; @@ -40,6 +41,7 @@ 0133003B249E792700A79FF1 /* ChooseCertificatePanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseCertificatePanel.swift; sourceTree = ""; }; 0156FD4D2498A18E003909E9 /* PushViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushViewModel.swift; sourceTree = ""; }; 016B434A249C9CEB0077D50D /* BoxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxView.swift; sourceTree = ""; }; + 01C356B024B5C062007A42F2 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; 01DFAB87248CD21B003664BE /* AirPush.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AirPush.app; sourceTree = BUILT_PRODUCTS_DIR; }; 01DFAB89248CD21B003664BE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 01DFAB8B248CD21B003664BE /* PushView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushView.swift; sourceTree = ""; }; @@ -108,6 +110,7 @@ 01E7CF2E249BBD080068D1FD /* PushConnectionPicker.swift */, 016B434A249C9CEB0077D50D /* BoxView.swift */, 0133003B249E792700A79FF1 /* ChooseCertificatePanel.swift */, + 01C356B024B5C062007A42F2 /* TextView.swift */, ); path = Views; sourceTree = ""; @@ -312,6 +315,7 @@ 01E7CF2D249B95DD0068D1FD /* ProgressIndicator.swift in Sources */, 0121A724249D33E800138001 /* MainWindowController.swift in Sources */, 0133003C249E792700A79FF1 /* ChooseCertificatePanel.swift in Sources */, + 01C356B124B5C062007A42F2 /* TextView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AirPushMac/Views/PushView.swift b/AirPushMac/Views/PushView.swift index 103bece..ef91d92 100644 --- a/AirPushMac/Views/PushView.swift +++ b/AirPushMac/Views/PushView.swift @@ -22,7 +22,6 @@ struct PushView: View { "The hexadecimal bytes of the device token for the target device", text: $viewModel.push.deviceToken) } - PushConnectionPicker(selection: $viewModel.push.connection) HStack { Button("Certificate:", action: chooseCertificate) Text(viewModel.certificate?.name ?? "none") @@ -32,7 +31,7 @@ struct PushView: View { Button("Send", action: send) .disabled(viewModel.isLoading) } - Spacer() + TextView(text: $viewModel.push.body) } .padding() } diff --git a/AirPushMac/Views/TextView.swift b/AirPushMac/Views/TextView.swift new file mode 100644 index 0000000..b7b5014 --- /dev/null +++ b/AirPushMac/Views/TextView.swift @@ -0,0 +1,62 @@ +// +// TextView.swift +// AirPushMac +// +// Created by Alexander Ignatev on 08.07.2020. +// Copyright © 2020 Alexandr Ignatyev. All rights reserved. +// + +import SwiftUI + +struct TextView: NSViewRepresentable { + @Binding var text: String + + func makeNSView(context: Context) -> NSScrollView { + let textView = NSTextView() + textView.delegate = context.coordinator + textView.isRichText = false + textView.autoresizingMask = [.width] + textView.translatesAutoresizingMaskIntoConstraints = true + textView.isVerticallyResizable = true + textView.isHorizontallyResizable = false + textView.isEditable = true + textView.font = NSFont.monospacedSystemFont( + ofSize: NSFont.systemFontSize, + weight: .regular + ) + let scrollView = NSScrollView() + scrollView.documentView = textView + scrollView.hasVerticalScroller = true + scrollView.borderType = .bezelBorder + return scrollView + } + + func updateNSView(_ scrollView: NSScrollView, context: Context) { + (scrollView.documentView as? NSTextView)?.string = text + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + final class Coordinator: NSObject, NSTextViewDelegate { + let parent: TextView + + init(_ parent: TextView) { + self.parent = parent + } + + func textDidChange(_ notification: Notification) { + guard let textView = notification.object as? NSTextView else { return } + parent.text = textView.string + } + } +} + +struct TextView_Previews: PreviewProvider { + static var previews: some View { + TextView(text: .constant("ABCabc123")) + .frame(width: 400, height: 300) + .padding() + } +}