在Mac应用中使用SwiftUI更改动画窗口大小
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Mac应用中使用SwiftUI更改动画窗口大小相关的知识,希望对你有一定的参考价值。
我正在为Mac应用程序使用SwiftUI,其中主窗口包含侧边栏视图和详细信息视图。选择侧边栏中的项目时,它将更改在详细视图中显示的视图。详细视图中显示的视图的大小不同,这会导致窗口的大小在显示时发生变化。但是,当窗口更改大小时,在更改大小的过程中看起来非常“刺眼”。有没有一种方法可以平滑地改变窗口大小的动画?
在详细视图中显示的视图:
// OneView.swift
struct OneView: View {
var body: some View {
VStack {
Text("One View").font(.headline).padding()
Text("Some stuff here.")
}
.frame(width: 400, height: 300)
}
}
// TwoView.swift
struct TwoView: View {
var body: some View {
VStack {
Text("Two View").font(.headline).padding()
Text("More stuff is here.")
}
.frame(width: 400, height: 500) }
}
// ThreeView.swift
struct ThreeView: View {
var body: some View {
VStack {
Text("Three View").font(.headline).padding()
Text("Another view goes here.")
}
.frame(width: 500, height: 200)
}
}
主要内容视图,详细信息视图和侧边栏视图:
// ContentView.swift
struct SidebarView: View {
@State private var selected = Set<String>()
private let items = ["One View", "Two View", "Three View"]
var body: some View {
List(items, id: .self, selection: $selected) { item in
NavigationLink(destination: DetailView(selection: item)) {
Text("(item)")
}
}
.listStyle(SidebarListStyle())
}
}
struct DetailView: View {
var selection: String
var body: some View {
switch selection {
case "One View":
return AnyView(OneView())
case "Two View":
return AnyView(TwoView())
case "Three View":
return AnyView(ThreeView())
default:
return AnyView(
Text("Some (selection) view here").frame(maxWidth: .infinity, maxHeight: .infinity)
)
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
SidebarView()
DetailView(selection: "One View")
}
}
}
答案
这里是可行方法的演示。我是从另一种观点看的,因为您需要重新设计解决方案才能采用它。
演示
1)需要调整窗口大小的视图
struct ResizingView: View {
public static let needsNewSize = Notification.Name("needsNewSize")
@State var resizing = false
var body: some View {
VStack {
Button(action: {
self.resizing.toggle()
NotificationCenter.default.post(name: Self.needsNewSize, object:
CGSize(width: self.resizing ? 800 : 400, height: self.resizing ? 350 : 200))
}, label: { Text("Resize") } )
}
.frame(minWidth: 400, maxWidth: .infinity, minHeight: 200, maxHeight: .infinity)
}
}
2)窗口的所有者(在这种情况下为AppDelegate
)
import Cocoa
import SwiftUI
import Combine
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
var subscribers = Set<AnyCancellable>()
func applicationDidFinishLaunching(_ aNotification: Notification) {
let contentView = ResizingView()
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), // just default
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
NotificationCenter.default.publisher(for: ResizingView.needsNewSize)
.sink(receiveCompletion: {_ in}) { [unowned self] notificaiton in
if let size = notificaiton.object as? CGSize {
var frame = self.window.frame
let old = self.window.contentRect(forFrameRect: frame).size
let dX = size.width - old.width
let dY = size.height - old.height
frame.origin.y -= dY // origin in flipped coordinates
frame.size.width += dX
frame.size.height += dY
self.window.setFrame(frame, display: true, animate: true)
}
}
.store(in: &subscribers)
}
...
以上是关于在Mac应用中使用SwiftUI更改动画窗口大小的主要内容,如果未能解决你的问题,请参考以下文章
如何向 swiftUI ScrollView 指示内容大小已更改?