Как установить пользовательский курсор в SKScene? (XCode, Swift4, Spritekit) - PullRequest
0 голосов
/ 29 апреля 2018

Я хочу использовать пользовательский курсор для моего проекта. Теперь использование одного из системных курсоров в XCode не так уж и важно, я просто вызываю:

NSCursor.crosshair() .set() 

(только пример)

Это работает нормально, но затем я пытаюсь установить свой собственный курсор следующим образом: (внутри didMove: для просмотра или внутри sceneDidLoad (), кажется, не имеет значения, какой именно.)

let image = NSImage(named: "hand1.png")
let spot = NSPoint(x: 4, y: 8)
let customCursor = NSCursor(image: image!, hotSpot: spot)
self.view!.addCursorRect(self.frame, cursor:customCursor)

Когда я пытаюсь собрать, в строке 3 появляется сообщение об ошибке "неожиданно найден ноль".

Итак, я изменил код так:

let image = NSImage(byReferencingFile: "hand1.png")
let spot = NSPoint(x: 4, y: 8)
let customCursor = NSCursor(image: image!, hotSpot: spot)
self.view!.addCursorRect(self.frame, cursor: customCursor)

Сейчас проект строится, но ничего не происходит. Курсор не меняется.

Я также попробовал эти строки здесь:

NSCursor.init(image: image!, hotSpot: spot)
NSCursor.set(customCursor)()

Опять же, проект строится, но курсор не меняется. Что я здесь не так делаю?

Я пытался следовать всем рекомендациям, которые мог найти, но документация Apple по событиям курсора не сильно помогает, поскольку ее сильно устаревшие и связанные с мышью темы, как правило, очень редки, так как большинство вещей посвящено ios. Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 06 мая 2018

Из NSImage(byReferencingFile:) документов,

Этот метод лениво инициализирует объект изображения. Это на самом деле не открыть указанный файл или создать любое представление изображения из его данные, пока приложение не попытается нарисовать изображение или запросить информацию об этом.

В результате изображение не загружается из файла при вызове метода addCursorRect(). Фактически, размер изображения (высота: 0, ширина: 0), как показано ниже.

if let image = NSImage(byReferencingFile:"cursorImage.png") {
    print("\(image.size)")
}

// (0.0, 0.0)

Я предлагаю вам использовать NSImage(named:) для создания изображения из файла:

if let image = NSImage(named:NSImage.Name("cursorImage.png")) {
    print("\(image.size)")
}

// (32.0, 32.0)

Кроме того, addCursorRect(image:,hotSpot:) следует вызывать только из метода resetCursorRects(). Из документов

Этот метод предназначен для вызова только resetCursorRects () метод. Если вызывается любым другим способом, результирующий прямоугольник курсора будет отброшен в следующий раз, когда прямоугольники курсора представления перестроен.

addCursorRect() - это метод экземпляра NSView, а для SpriteKit представлением является SKView, которое наследуется от NSView. Соответственно, вы можете создать подкласс SKView, переопределить метод подкласса addCursorRect() и изменить класс представления (на наш подкласс SKView) в раскадровке.

В качестве альтернативы, вы можете сделать это, расширив SKView и переопределив метод resetCursorRects(). Например,

Для Xcode 9,3

extension SKView {
    override open func resetCursorRects() {
        if let image = NSImage(named:NSImage.Name(rawValue:"cursorImage.png")) {
            let spot = NSPoint(x: 0, y: 0)
            let customCursor = NSCursor(image: image, hotSpot: spot)
            addCursorRect(visibleRect, cursor:customCursor)
        }
    }
}

Для Xcode 9.2

extension SKView {
    override open func resetCursorRects() {
        if let image = NSImage(named:NSImage.Name("cursorImage.png")) {
            let spot = NSPoint(x: 0, y: 0)
            let customCursor = NSCursor(image: image, hotSpot: spot)
            addCursorRect(visibleRect, cursor:customCursor)
        }
    }
}

Для более старых версий Xcode:

extension SKView {
    override open func resetCursorRects() {
        if let path = Bundle.main.path(forResource: "cursorImage", ofType: "png") {
            if let image = NSImage(contentsOfFile:path) {
                let spot = NSPoint(x: 0, y: 0)
                let customCursor = NSCursor(image: image, hotSpot: spot)
                addCursorRect(visibleRect, cursor:customCursor)
            }
        }
    }
}

Project Navigator с выделенным курсором.

enter image description here

...