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

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

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

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

Xcode

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

Swift

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

Q&A

解決済

1回答

2381閲覧

Swiftで作るアプリの背景が透明ステータスバーに届かない

Fictitious0x

総合スコア5

MacOS(OSX)

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/03/30 13:40

編集2020/03/30 23:18

前提・実現したいこと

Xcodeを用いてmacOS用のSwiftアプリケーション制作を試みています。
アプリケーションの背景として画像(以下の図では白い画像に置き換えています)を表示しようと思い立ち、
タイトルバーが無い方が雰囲気が良いと考え、初心者ながら調べつつタイトルバーを消すことには成功したものの、
イメージに".scaledToFill()"をつけてリサイズしても、ウィンドウのアスペクト比によってタイトルバーがあった部分まで画像が届かないことがあります。
この形が理想ですが、
ウィンドウのアスペクト比を変えるとステータスバーまで画像が届かなくなり、
絶妙な位置に境目を作ってしまうこともあります

試したこと

・インターネットをかなり探したつもりですが、タイトルバーを消す方法を紹介している記事自体が数える程しか見つからず、その上でウィンドウをイメージで一杯にする例は見つかりませんでした。
・画像を".resizable()"とした上で、".scaleEffect(2)"で画像のサイズを2倍にするとタイトルバー分まで埋まるようにはなりましたが、ウィンドウのアスペクト比が元の画像に近いのならば出来る限り表示しなければ勿体ないような気もします。それとも諦めるべきでしょうか。
・ウィンドウの縦(タイトルバー含む)と横の長さを取得し、画像のサイズと照らし合わせての計算により".resizable()"と".scaledToFill()"に相当するプログラムを自分で作ることを考えました。こちらもかなり調べましたが、iOSNSRect等々の型変換にギブアップして最初の問題に立ち戻ることを数回繰り返した結果、こうして質問させて頂く流れとなりました。

初心者が滲み出る質問文になったこと申し訳なく思います。何方かご教授頂ければ幸いです。

現在のプログラム

(BackgroundView.swift) アプリケーション内で背景を変更できる機能を後々付けるつもりで、プログラムを分けています

Swift

1struct BackgroundView: View { 2 let number: Int 3 var body: some View { 4 Image("Background_(number)") 5 .resizable() 6 .scaledToFill() 7 } 8}

(ContentView.swift)

Swift

1struct ContentView: View { 2 var body: some View { 3 BackgroundView(number: 4) 4 } 5}

(AppleDelegate.swift) SwiftUIのXcode 11におけるCocoa Classの設定方法が分からず、AppleDelegate.swiftに入れてみると上手く動作したので、これで良いか、と思いプログラムを加えて行った次第です

Swift

1import Cocoa 2import SwiftUI 3 4@NSApplicationMain 5class AppDelegate: NSObject, NSApplicationDelegate { 6 7 var window: NSWindow! 8 9 10 func applicationDidFinishLaunching(_ aNotification: Notification) { 11 // Create the SwiftUI view that provides the window contents. 12 let contentView = ContentView() 13 14 // Create the window and set the content view. 15 window = NSWindow( 16 contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), 17 styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], 18 backing: .buffered, defer: false) 19 window.center() 20 window.setFrameAutosaveName("Main Window") 21 window.contentView = NSHostingView(rootView: contentView) 22 window.makeKeyAndOrderFront(nil) 23 24 //ここから 25 26 window?.titlebarAppearsTransparent = true 27 window?.titleVisibility = .visible 28 window?.styleMask.insert(.fullSizeContentView) 29 // window?.styleMask = .fullSizeContentView 30 window?.isOpaque = false 31 window?.backgroundColor = NSColor(white: 1, alpha: 0) 32 33 //ここまでをデフォルトのコードに加えています 34 } 35 36 func applicationWillTerminate(_ aNotification: Notification) { 37 // Insert code here to tear down your application 38 } 39 40 41}

補足情報(FW/ツールのバージョンなど)

XCodeのバージョンは11.4 (11E146)です。
OSはmacOS Catalina 10.15.3です。

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

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

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

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

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

hoshi-takanori

2020/03/30 22:07 編集

ご自分で試したソースコードを貼っていただけるとこちらでも試してみようかという気になるのですが…。 あと、Swift タグだけだと哀しいことに iOS の質問かと思ってしまうので、MacOS(OSX) タグも追加していただけると良いと思います。
Fictitious0x

2020/03/30 22:17

ご意見有り難う御座います。タグ、そして質問にプログラムを加えました。
guest

回答1

0

ベストアンサー

window の styleMask に .fullSizeContentView を設定した場合、NSView はタイトルバーの領域まで広がるのに、SwiftUI の View はタイトルバーの領域には広がらないようですね。
BackgroundView がタイトルバーの領域に描画されるのは、ウィンドウを横に広げた(または縦に縮めた)場合に上下にはみ出す部分が、タイトルバー部分だけクリッピングされずに表示されているようです。(画像の上下 20px ほど色を変えて観察すると、下は切れてるのに上は切れてなかったりするのが分かります。)

とりあえず、背景画像を表示するだけであれば、背景画像だけ NSView 側で設定すればいいと思います。
(なお、macOS の次のバージョンで動くかどうかは保証の限りではないかも。)

swift

1 func applicationDidFinishLaunching(_ aNotification: Notification) { 2 // Create the SwiftUI view that provides the window contents. 3 let contentView = ContentView() 4 5 // Create the window and set the content view. 6 window = NSWindow( 7 contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), 8 styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], 9 backing: .buffered, defer: false) 10 window.center() 11 window.setFrameAutosaveName("Main Window") 12 // window.contentView = NSHostingView(rootView: contentView) // この行は削除 13 window.makeKeyAndOrderFront(nil) 14 15 //ここから 16 17 window?.titlebarAppearsTransparent = true 18 window?.titleVisibility = .visible 19 window?.styleMask.insert(.fullSizeContentView) 20 // window?.styleMask = .fullSizeContentView 21 window?.isOpaque = false 22 window?.backgroundColor = NSColor(white: 1, alpha: 0) 23 24 //ここまでをデフォルトのコードに加えています 25 26 // 背景画像を CALayer で設定 27 let imageLayer = CALayer() 28 imageLayer.contents = NSImage(named: "Background_4") 29 imageLayer.contentsGravity = .resizeAspectFill 30 window.contentView?.layer = imageLayer 31 window.contentView?.wantsLayer = true 32 33 // SwiftUI の View を追加 34 let hostingView = NSHostingView(rootView: contentView) 35 hostingView.autoresizingMask = [.width, .height] 36 hostingView.frame = window.contentView!.frame 37 window.contentView?.addSubview(hostingView) 38 }

投稿2020/03/31 14:04

hoshi-takanori

総合スコア7901

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

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

Fictitious0x

2020/03/31 23:34

AppDelegate.swiftにコードを加えると、何故か画像が180度回転した状態になってしまっていたので、最後に"window.contentView?.rotate(byDegrees: 180)"と加えると上手く動作しました。御回答頂き、本当に有り難う御座いました!
Fictitious0x

2020/04/01 00:35

画像の反転はこちらのミスでした……。他の画像を入れると通常のままで動きました。失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問