gpt4 book ai didi

swift - 不移动鼠标后将其隐藏在 Mac 应用程序中

转载 作者:搜寻专家 更新时间:2023-10-31 22:29:27 25 4
gpt4 key购买 nike

我目前正在使用 Swift 为 Mac 制作幻灯片应用程序。在此应用程序中,我想在幻灯片放映时隐藏鼠标,并且鼠标有一段时间没有移动,就像在 Quick Time Player 中所做的那样。

现在我尝试了很多使用 NSCursor.hide()NSCursor.unhide() 以及 NSCursor.setHiddenUntilMouseMoves() ,但没有一个完全有效。

首先,我未能让它在我的主 ViewController 中调用 mouseMoved 函数,其次,即使我根本没有触摸触控板,NSCursor.setHiddenUntilMouseMoves() 似乎并不总是有效。就在更改幻灯片中图像的代码之后,我看到图像正在更改,但使用调试器时,当光标未隐藏时,它不会停在该行代码上。

有人能告诉我如何让它工作的一般方法吗?我很确定这不是一件很奇特的事情,而且有比我正在尝试的方法更容易的方法。

下面是我试过的:

import Cocoa

class DiashowViewController: NSViewController {

enum DiashowState {
case playing
case paused
case stopped
}

var files: [URL]?
var diaTimer = Timer()
var diashowState: DiashowState = .stopped

var mouseTimer = Timer()

@IBOutlet weak var diaView: NSImageView!

override func viewDidLoad() {
super.viewDidLoad()

}

override var representedObject: Any? {
didSet {
// Update the view, if already loaded.

}
}

func playDiashow() {
if diashowState == .paused {
diaTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.changeDia), userInfo: nil, repeats: true)
diashowState = .playing
NSCursor.setHiddenUntilMouseMoves(true)
}
}

func playDiashow(withFiles files: [URL]) {
stopDiashow()

self.files = files
diashowState = .paused

playDiashow()
changeDia()
}

func pauseDiashow() {
if diashowState == .playing {
diaTimer.invalidate()
diashowState = .paused
}
}

override func mouseMoved(with event: NSEvent) {
print("MOUSE MOVED")
}

func stopDiashow() {
pauseDiashow()
diaView.image = nil
files = nil
diashowState = .stopped
}

func changeDia() {
if diashowState == .playing {
let i = Int(arc4random_uniform(UInt32(files!.count)))
let thisDiaURL = files![i]
let thisDia = NSImage(contentsOf: thisDiaURL)
thisDia?.size = NSSize(width: (thisDia?.representations.first?.pixelsWide)!, height: (thisDia?.representations.first?.pixelsHigh)!)
diaView.image = thisDia
NSCursor.setHiddenUntilMouseMoves(true)
print("HIDE MOUSE")
}
}

}

提前致谢!

最佳答案

要接收 mouseMoved 事件,您需要将 NSTrackingArea 添加到 View 中,您可能已经发现 setHiddenUntilMouseMoves 设置是单发的,并且在该状态下鼠标移动后需要重新断言。

我没有尝试解开您的代码,而是制作了一个演示项目,在该项目中我设置了一个带有 View 和按钮的窗口。 View 颜色从红色变为绿色以显示状态。

enter image description here

class ViewController: NSViewController {

@IBOutlet weak var xview: NSView!

override func viewDidLoad() {
super.viewDidLoad()
xview.wantsLayer = true
}

//1.
var isPresentingSlideshow = false
@IBAction func toggle(_ sender: Any) {

if(isPresentingSlideshow) {
isPresentingSlideshow = false
xview.layer?.backgroundColor = NSColor.green.cgColor
teardownTracking()
}
else {
isPresentingSlideshow = true
xview.layer?.backgroundColor = NSColor.red.cgColor
setupTracking()
}
}

//2.
var trackingArea:NSTrackingArea?
func setupTracking() {
let area = NSTrackingArea(rect: xview.bounds, options: [.activeAlways,.mouseEnteredAndExited,.mouseMoved,.inVisibleRect] , owner: self, userInfo: nil)
xview.addTrackingArea(area)
trackingArea = area
}

//3.
func teardownTracking() {
if let trackingArea = trackingArea {
xview.removeTrackingArea(trackingArea)
self.trackingArea = nil
NSCursor.setHiddenUntilMouseMoves(false)
}
}

//4.
var cursorHideState = false
override func mouseMoved(with event: NSEvent) {
super.mouseMoved(with: event)

if !cursorHideState {
cursorHideState = true
//5.
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
[weak self] in
if let _ = self?.trackingArea {
NSCursor.setHiddenUntilMouseMoves(true)
self?.cursorHideState = false
}
}
}
}

}

这里发生的事情是。

  1. 在播放/不播放状态之间切换并反射(reflect)在颜色状态中的简单切换 Action 。
  2. 向 View 添加一个 NSTrackingArea。所有者是此 View Controller ,因此它将接收 mouseMoved: 事件。需要选项 .mouseMoved 来设置它。
  3. 在不播放幻灯片时从 View 中删除跟踪区域并将 setHiddenUntilMouseMoves 设置为 false。
  4. mouseMoved: 处理程序
  5. 只要跟踪区域存在且尚未等待,setHiddenUntilMouseMoves 就会在两秒后设置为真。请注意,对 self 的弱引用可防止此处可能的保留循环。

这并不完美,因为您可能会发现光标在离开窗口后会隐藏一次,但应该让您朝着正确的方向前进。

关于swift - 不移动鼠标后将其隐藏在 Mac 应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41416227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com