提问人:KanKonga 提问时间:9/17/2023 最后编辑:WillekeKanKonga 更新时间:9/18/2023 访问量:63
为什么这个 swift 代码不显示行和动画?
Why this swift code does not show up line and the animation?
问:
为什么 does get's 没有显示在窗口中,尽管它在 ?MyViewController
contentViewController: MyViewController()
我不在故事板或 XIB 上,我不想使用 nib 文件。
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create a new window
window = NSWindow(contentViewController: MyViewController())
// Make the window visible
window.makeKeyAndOrderFront(nil)
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
}
class MyViewController: NSViewController {
override func loadView() {
let view = NSView(frame: NSMakeRect(0, 0, 400, 400))
self.view = view
// Create a shape layer for the rectangle
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = NSColor.black.cgColor
shapeLayer.lineWidth = 2
shapeLayer.lineJoin = .round
shapeLayer.lineDashPattern = [NSNumber(value: 6), NSNumber(value: 4)]
// Create a path for the rectangle
let path = CGMutablePath()
path.addRect(NSRect(x: 50, y: 50, width: 100, height: 100))
shapeLayer.path = path
// Create an animation for the dashed line
let animation = CABasicAnimation(keyPath: "lineDashPhase")
animation.fromValue = 0
animation.toValue = shapeLayer.lineDashPattern?.reduce(0) { $0 + $1.intValue }
animation.duration = 1
animation.repeatCount = .infinity
shapeLayer.add(animation, forKey: "lineDashPhase")
// Add the shape layer to the view hierarchy
view.layer?.addSublayer(shapeLayer)
}
}
答:
0赞
apodidae
9/18/2023
#1
我不在故事板或 XIB 上,我不想使用 nib 文件。
如果要使用编程方法,则不需要基本窗口的控制器,如下面的演示所示。若要在 Xcode 中运行以下内容,请先创建一个 Swift 项目,添加“main.swift”文件,然后删除预先提供的 AppDelegate 文件。将此代码复制/粘贴到“main”文件中并运行。我为您的视图添加了绿色背景,以便您可以看到它的边界。您需要将 .wantsLayer 设置为 true,然后将视图作为子视图添加到 window.contentView。
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
var window:NSWindow!
var view: NSView!
func buildMenu() {
let mainMenu = NSMenu()
NSApp.mainMenu = mainMenu
// **** App menu **** //
let appMenuItem = NSMenuItem()
mainMenu.addItem(appMenuItem)
let appMenu = NSMenu()
appMenuItem.submenu = appMenu
appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q")
}
func buildWnd() {
let _wndW : CGFloat = 400
let _wndH : CGFloat = 400
window = NSWindow(contentRect:NSMakeRect(0,0,_wndW,_wndH),styleMask:[.titled, .closable, .miniaturizable, .resizable], backing:.buffered, defer:false)
window.center()
window.title = "Swift Test Window"
window.makeKeyAndOrderFront(window)
// **** CAShapeLayer with Animation **** //
view = NSView(frame: NSMakeRect(0, 0, 400, 400))
window.contentView!.addSubview (view)
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.green.cgColor
// Create a shape layer for the rectangle
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = NSColor.black.cgColor
shapeLayer.lineWidth = 2
shapeLayer.lineJoin = .round
shapeLayer.lineDashPattern = [NSNumber(value: 6), NSNumber(value: 4)]
// Create a path for the rectangle
let path = CGMutablePath()
path.addRect(NSRect(x: 50, y: 50, width: 100, height: 100))
shapeLayer.path = path
// Create an animation for the dashed line
let animation = CABasicAnimation(keyPath: "lineDashPhase")
animation.fromValue = 0
animation.toValue = shapeLayer.lineDashPattern?.reduce(0) { $0 + $1.intValue }
animation.duration = 1
animation.repeatCount = .infinity
shapeLayer.add(animation, forKey: "lineDashPhase")
// Add the shape layer to the view hierarchy
view.layer?.addSublayer(shapeLayer)
// **** Quit btn **** //
let quitBtn = NSButton (frame:NSMakeRect( _wndW - 50, 10, 40, 40 ))
quitBtn.bezelStyle = .circular
quitBtn.autoresizingMask = [.minXMargin,.maxYMargin]
quitBtn.title = "Q"
quitBtn.action = #selector(NSApplication.terminate)
window.contentView!.addSubview(quitBtn)
}
func applicationDidFinishLaunching(_ notification: Notification) {
buildMenu()
buildWnd()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
let appDelegate = AppDelegate()
// **** main.swift **** //
let app = NSApplication.shared
app.delegate = appDelegate
app.setActivationPolicy(.regular)
app.activate(ignoringOtherApps:true)
app.run()
评论
0赞
KanKonga
9/18/2023
在 xcode 中,我没有 main.swift 文件,只有 appdelegate 文件。所以,我不知道把最后 6 行代码放在哪里。我用 xCode、XIB、Swift 创建了这个项目,还是做错了什么。
0赞
KanKonga
9/18/2023
更新:我刚刚删除了最后 6 行,您要求将其放入 main.swift 中,它工作正常。必须放置最后 6 行吗?除了运行 appdelegate 之外,它还有什么其他用途吗?
0赞
apodidae
9/18/2023
您必须使用 Xcode 的“文件”菜单创建“main.swift”,即文件/新建/文件并选择 Swift 文件类型。点击“下一步”并输入“main.swift”作为文件名,然后点击创建按钮。应该看起来像上面编辑过的答案。我删除了 AppDelegate 文件,因为 Xcode 不允许两个 AppDelegate。如果你愿意,你可以继续使用预先提供的AppDelegate,这显然是你所做的。
-2赞
Duncan C
9/18/2023
#2
看起来您的问题至少部分与 Willeke 链接的答案相同(来自 Matt)
问题是你从来没有说过
view.wantsLayer = true
因此,您的视图没有图层,并且将背景颜色应用于 图层没有效果,因为(正如我刚才所说)您的视图没有图层。 所以风景在那里,但你看不到它;它是透明的,就像 隐形人。
尝试在创建视图后添加该行。view.wantsLayer = true
评论
1赞
Willeke
9/18/2023
请不要复制答案。改为将问题标记为重复。
评论