꼭 만들어서 사용하고 싶은 mac app이 생겨서 재미로 mac app 개발을 시작했습니다. 시간 날때 틈틈이 개발해서 빨리 제가 사용하고 싶습니다 🫡 화면 element 자체는 많지 않고 디테일한 UI 작업은 필요없는 앱이라 속도감을 위해서 SwiftUI로 진행하게 되었습니다.
iOS 앱을 만들 때는 Window 자체를 투명하게 만들어 본 적이 없었는데, mac 앱 작업 중에 window를 투명하게 만들어 볼 일이 생겼습니다.
아래 처럼 TransparentWindowView를 만들고
SwiftUI에서 사용할 수 있도록 NSViewRepresentable struct를 만들어 준 다음,
body View의 background로 설정해주는 방식이었습니다.
class TransparentWindowView: NSView {
override func viewDidMoveToWindow() {
window?.titlebarAppearsTransparent = true // title bar 도 투명하게 만들기 위해 설정
window?.titleVisibility = .hidden // title을 숨기기 위해 설정
window?.backgroundColor = .windowBackgroundColor.withAlphaComponent(0.0) // window 백그라운드 색상 설정
super.viewDidMoveToWindow()
}
}
struct TransparentWindow: NSViewRepresentable {
func makeNSView(context: Self.Context) -> NSView { return TransparentWindowView() }
func updateNSView(_ nsView: NSView, context: Context) { }
}
iOS 에서는 한 번도 사용한 적 없던 NSView는 iOS의 UIView와 유사합니다. 다만 직접 NSView를 initialize해서 사용하지는 않고 subclassing에서 사용해야합니다.
Drawing, printing과 event handling을 담당하는 infrastructure라고 설명이 되어있습니다.
window의 백그라운드 설정만 변경하려면
"window?.backgroundColor" 값만 변경해주면 됩니다.
저는 window 뿐만 아니라 상단에 타이틀이 나오는 바 부분도 투명도를 주고 타이틀도 없애고 싶어서 아래 코드들도 추가해 주었습니다.
window?.titlebarAppearsTransparent = true // title bar 도 투명하게 만들기 위해 설정
window?.titleVisibility = .hidden // title을 숨기기 위해 설정
여기서 하나 알게 된 점이,
body View의 프로퍼티 중에 frame size가 설정되어 있다면 위의 title bar transparency 설정이 동작하지 않는 다는 것이었습니다.
그렇기 때문에 title bar transparency를 설정하려면 고정값은 사용하면 안될 것 같았습니다.
또 하나 알게된 것은 mac app은 드래그로 윈도우 사이즈를 줄일 수 있는데, 그럴 때 view property들에 고정값을 사용해 두지 않았다면 윈도우 사이즈에 맞춰서 적절하게 view property 사이즈가 변하게 됩니다. 윈도우를 늘리면 커지고 작게하면 같이 줄어듭니다.
모바일과 동작하는 방식이 다르다보니 작은 앱이어도 개발 과정 중에서 새로 알아가는 것들이 많이 생길 것 같습니다.
참고자료
https://forums.developer.apple.com/forums/thread/694837
https://stackoverflow.com/questions/5283218/what-is-the-difference-between-uiview-and-nsview
https://stackoverflow.com/questions/47759424/how-to-colour-the-titlebar-of-nswindow