質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

956閲覧

SwiftUIでNSTextViewをラップすると高さが合わない

Tokkin_Masshu

総合スコア2

Cocoa

CocoaはMac OS X用のアプリケーションを構築する為の主要なフレームワークのひとつです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/01/20 10:16

実現したいこと

SwiftUIでmacOSの日記アプリを作っていて、SwiftUI標準のTextEditorでは機能が足りないのでNSTextViewをNSViewRepresentableでラップして使おうとしました。NSTextViewがViewを埋め尽くしてくれるのが理想です。
下のコードが最低限の実装です。

Swift

1import SwiftUI 2import AppKit 3 4struct TextView: NSViewRepresentable { 5 @Binding var text: String 6 7 func makeNSView(context: Context) -> NSTextView { 8 let nsTextView = NSTextView() 9 nsTextView.delegate = context.coordinator 10 nsTextView.string = self.text 11 return nsTextView 12 } 13 14 func updateNSView(_ nsTextView: NSTextView, context: Context) { 15 nsTextView.string = self.text 16 } 17 18 func makeCoordinator() -> Coordinator { 19 Coordinator(self) 20 } 21} 22 23extension TextView { 24 class Coordinator: NSObject, NSTextViewDelegate { 25 var parent: TextView 26 27 init(_ parent: TextView) { 28 self.parent = parent 29 } 30 31 func textDidChange(_ notification: Notification) { 32 guard let nsTextView = notification.object as? NSTextView else { return } 33 self.parent.text = nsTextView.string 34 } 35 } 36} 37 38//MARK: - プレビュー 39struct TextView_Previews: PreviewProvider { 40 static var previews: some View { 41 TextView(text: .constant("サンプルテキスト\nサンプルテキスト\nサンプルテキスト\nサンプルテキスト\nサンプルテキスト\nサンプルテキスト")) 42 .frame(width: 600, height: 600, alignment: .center) 43 .border(Color.green) 44 .padding() 45 .previewDisplayName("TextView") 46 } 47}

これでテキストの編集は問題なくできるのですが、画像のようにNSTextViewがSwiftUIのViewの端まで広がらず、高さが合いません。
スクリーンショット

#やってみたこと

  • makeNSView、updateNSViewメゾットの中にnsTextView.frame = .init(x: 0, y: 0, width: 400, height: 300)を入れて直接サイズを変えてみようとしました。この方法でwidthは変わりましたがheightを伸ばすことはできませんでした。
  • 制約を使えばいいのかな、と考えて、空のNSViewにnsTextViewをaddSubView()で入れて、NSLayoutConstraint.activate()で4つの角を合わせました。この方法ではそもそもNSTextView自体が表示されませんでした。
  • XcodeのデバッグツールでViewの階層構造を確認しました。緑の枠の中でグレーになっている部分はNSTextViewの一部ではないことを確認しました。
  • Googleで「Swift UITextView UIViewRepresentable」や「Swift UIViewRepresentable size」で検索をかけました。(「NS」ではなく「UI」にしているのは、UIKitの方が情報が多いからです。基本的に違いはありません。)何時間か漁りましたが、目当てのものは(下記を除いて)見つかりませんでした。
  • GitHubにMacEditorTextViewというコードがあるのを見つけました。これはちゃんと表示されますが、スクロール機能がついてしまっています。

 これまで何度もSwiftUIでNSTextViewを使おうと試みてきましたが、この問題がどうしても解けません。どなたかご教示していただけないでしょうか。何か記述不足があればご指摘ください。
よろしくお願い致します。
#環境
macOS 11.1
Xcode 12.3
Swift 5.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/01/20 20:40

スクロール機能がないと行数が増えてテキストがビューからはみ出した時に困るのでは?
Tokkin_Masshu

2021/01/21 10:49

スクロールの機能はSwiftUIのScrollViewで後からつけようと考えています。Apple純正のメモアプリってスクロールできるNSTextViewの一番上にラベルがついていて、それを実現する時にTextViewの内側にスクロールがあると困るんですよね......。 字数制限があった場合、ということでお願いします。m(-_-)m
Tokkin_Masshu

2021/01/21 10:51

「一番上のラベル」というのは、編集時刻を表示しているあれのことです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問