Closed Dybo007 closed 5 months ago
Actually, you don't need to change anything in DynamicNotch, and should already work.
Note that you should declare DynamicNotch
as an instance variable, instead of a local one, which is likely what is causing your problem.
If you need more help, please send your code (or fragments of it) :)
As i said, i'm new to swift. Here's how i'm calling it:
func checkOutputDevice() {
if let outputDevice = simplyCA.defaultOutputDevice {
if outputDevice.name.contains("AirPods") {
VolumeWindow.isAirPodsConnected = true
} else {
VolumeWindow.isAirPodsConnected = false
}
let notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch.show(for: 5)
if VolumeWindow.externalDisplay {
let notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch.show(on: NSScreen.screens[1], for: 5)
}
}
}
What i'm doing wrong?
so to make DynamicNotchInfo an instance variable, you would need to do something like:
...class declaration
var notch: DynamicNotchInfo?
func checkOutputDevice() {
if let outputDevice = simplyCA.defaultOutputDevice {
if outputDevice.name.contains("AirPods") {
VolumeWindow.isAirPodsConnected = true
} else {
VolumeWindow.isAirPodsConnected = false
}
notch = DynamicNotchInfo(
icon: app,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(for: 5)
if VolumeWindow.externalDisplay {
notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(on: NSScreen.screens[1], for: 5)
}
}
}
...continue code
There may be some mistakes here, but here's the rough structure your code should have 😉
Sorry, it was late (5am) yesterday...
class MyDynamicNotchInfo {
let icon: Image
let title: String
let titleColor: Color
let description: String
let style: DynamicNotch.Style
init(icon: Image, title: String, titleColor: Color, description: String, style: DynamicNotch.Style) {
self.icon = icon
self.title = title
self.titleColor = titleColor
self.description = description
self.style = style
}
}
struct VolumeView: View {
var notch = MyDynamicNotchInfo?.self // if not .self, "Expected member name or constructor call after type name"
and i'm getting:
No problem!
It should look like this:
struct VolumeView: View {
@State var notch: MyDynamicNotchInfo?
The @State
is needed in SwiftUI views, and you should use a colon when assigning a type rather than an actual value :)
My bad!!! Thanks for the colon trick!! Sorry for that!
Still getting Value of type 'MyDynamicNotchInfo' has no member 'show'
in my checkOutputDevice()
method. How to call show()
from my class?
import SwiftUI
import DynamicNotchKit
class MyDynamicNotchInfo {
let icon: Image
let title: String
let titleColor: Color
let description: String
let style: DynamicNotch.Style
init(icon: Image, title: String, titleColor: Color = .white, description: String, style: DynamicNotch.Style) {
self.icon = icon
self.title = title
self.titleColor = titleColor
self.description = description
self.style = style
}
}
struct VolumeView: View {
@State var notch: MyDynamicNotchInfo?
var body: some View {...}
func checkOutputDevice() {
notch = MyDynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(for: 5)
if VolumeWindow.externalDisplay {
notch = MyDynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(on: NSScreen.screens[1], for: 5)
}
}
}
Can you confirm i'm not doing something wrong here?
Many thanks for all your work and your help!!
This might not be perfect as for your use case (so please edit it to your needs), but something like this will work better :)
import SwiftUI
import DynamicNotchKit
struct VolumeView: View {
@State var notch: DynamicNotchInfo? // I am using DynamicNotchInfo instead of MyDynamicNotchInfo here
var body: some View {...}
func checkOutputDevice() {
notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(for: 5)
if VolumeWindow.externalDisplay {
notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(on: NSScreen.screens[1], for: 5)
}
}
}
Since your MyDynamicNotchInfo
doesn't have a show()
method, it wasn't working. I assume you meant to use DynamicNotchInfo
instead, so I used that in my example above. If you did mean to use MyDynamicNotchInfo
, you would need to implement a show()
method there.
It was a mistake yes... sorry. The code you gave me is the code i tried first, but it doesn't work, it still display 2 floating windows, one above the other... don't know why but... No matter, i don't want to take you all your time for my little problem... Thanks for all!!
It's alright! I also just realized that I forgot to add the hiding part, try this:
import SwiftUI
import DynamicNotchKit
struct VolumeView: View {
@State var notch: DynamicNotchInfo? // I am using DynamicNotchInfo instead of MyDynamicNotchInfo here
var body: some View {...}
func checkOutputDevice() {
notch?.hide() // hide :)
notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(for: 5)
if VolumeWindow.externalDisplay {
notch?.hide() // hide :)
notch = DynamicNotchInfo(
icon: ap,
title: "Airpods",
description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés",
style: .floating
)
notch?.show(on: NSScreen.screens[1], for: 5)
}
}
}
Another option would be to use the setContent() method instead of initializing a new DynamicNotchInfo, which could potentially be seen as more efficient, and might be the way to go.
Wow!! Tricky!! But no luck with that too... Tell me more about the setContent() method?
It is documented here.
This way, instead of redoing notch = DynamicNotchInfo(...)
every time it's triggered, you could simply intitialize it once, and every time you need to show the popup, you can simply do: notch.setContent(...)
, then show it.
for some reason, i couldn't get it to work... it doesn't even display!!
func checkOutputDevice() {
notch?.setContent(icon: ap, title: "Airpods", description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés")
if VolumeWindow.externalDisplay {
notch?.setContent(icon: ap, title: "Airpods", description: VolumeWindow.isAirPodsConnected ? "Connectés" : "Déconnectés")
}
}
Is this good?
First, you will need to initiate the DynamicNotch, since currently, you are trying to call a function on a nil
value.
Also, you will still need to have the show()
method :)
I'm still using @State var notch: DynamicNotchInfo?
...
Sorry, i couldn't get it to work. i'm thinking to leave it like this, it's gonna be less beautiful, but no matter. You're not gonna create my app for me... So, many thanks for what you've done for now and for this package!!
Today it look like this and it's good enough:
Again, many thanks for all!
I got it to work!!! The problem comes from the fact that i display it on external screen...
If i delete the if VolumeWindow.externalDisplay {
statement, it work on main screen! if i keep the if statement, it work on the external display but not on the main... Normal behaviour?
Sorry for the late answer!
Today it look like this and it's good enough:
This looks absolutely amazing! If you ever end up publishing the app - let me know, I would be a proud user :)
If i delete the if VolumeWindow.externalDisplay { statement, it work on main screen!
That's interesting... I'm guessing that this is MacOS doing something weird, but I can't be completely sure without looking at the full code.
This looks absolutely amazing! If you ever end up publishing the app - let me know, I would be a proud user :)
I'm sure you can do better than me!! I've just modified part of your work... It's an app than show battery level around the (real) notch on notched MacBooks, and change the volume HUD which is ugly in my opinion... just my opinion! Different volume HUD styles, and positions can be set, inspired by MediaMate app, but without media player.
That's interesting... I'm guessing that this is MacOS doing something weird, but I can't be completely sure without looking at the full code.
It can comes from my code, i'm not a dev, i just started xcode about 6 month ago just to create this notched battery level app, and added some features from time to time, getting this entire app at last, with the help of AI and maaany internet researches... Still doesn't know swiftui, i'm just "swimming"... this is why i'm not planning to release it, as it's not well written... But i'm pretty sure anyone can do better than this!!
If some news from my side, i'll come back to you!
Thanks for all, your help, your patience and your work!! Take care!!
PS: sorry for my poor english, french here...
No problem! Je connais un peu le français aussi :) I'm actually a MediaMate user, and I totally agree that the system HUD is indeed ugly haha!
Anyways, good luck on your app!
Je connais un peu le français aussi :)
Quebec? Tu a appris où le français, à l'école?
Oui! Je vais à une école d'immersion française (pas en Quebec) 😁
Super!! Si tu passe un jour en France, fais moi signe!! Bon courage et bonne continuation!! Salut l'ami!!
HI, i'm displaying a message when i connect something, and another one when it's disconnected. If i disconnect right after connecting, i'm getting two floating window, which i want to avoid. How to hide the first one? I think it's in the "public func show", but all my changes doesn't change anything... I'm new to swift... does the "timer.invalidate()" supposed to do this thing? I have also replaced the "return" in "if self.isVisible { return }" to "self.hide()", with no luck.
Help please! Thanks.