Отслеживание местоположения при наведении в SwiftUI

от автора

Какое-то время у нас был только модификатор onHover(perform:) в SwiftUI, который вызывается, когда пользователь перемещает указатель над рамкой view (представление, вью, вьюшка) или от неё. Раньше не было официального способа непрерывного отслеживания местоположения указателя. Это изменилось с введением onContinuousHover(coordinateSpace:perform:) в macOS 13 и iPadOS 16.

Новый модификатор позволяет нам читать текущую HoverPhase и сообщает точное местоположение указателя, когда он находится в пределах границ view. Давайте посмотрим на это в действии.

Чтение фазы наведения и местоположения указателя

В этом примере мы собираемся определить простой прямоугольник со скруглёнными углами и применить к нему onContinuousHover(). Активная фаза наведения содержит местоположение указателя, мы собираемся сохранить его в переменной State. Мы также собираемся зарегистрироваться, когда указатель находится во view.

struct ContentView: View {     @State private var hoverLocation: CGPoint = .zero     @State private var isHovering = false          var body: some View {         RoundedRectangle(cornerRadius: 20, style: .continuous)             .fill(.indigo)             .frame(width: 400, height: 300)             .onContinuousHover { phase in                 switch phase {                 case .active(let location):                     hoverLocation = location                     isHovering = true                 case .ended:                     isHovering = false                 }             }     } }

Чтобы проверить, работает ли наш код должным образом, мы поместим view Text с координатами указателя в overlay. Текст будет отображаться только тогда, когда пользователь наводит курсор на прямоугольник.

struct ContentView: View {     @State private var hoverLocation: CGPoint = .zero     @State private var isHovering = false          var body: some View {         RoundedRectangle(cornerRadius: 20, style: .continuous)             .fill(.indigo)             .frame(width: 400, height: 300)             .onContinuousHover { phase in                 switch phase {                 case .active(let location):                     hoverLocation = location                     isHovering = true                 case .ended:                     isHovering = false                 }             }             .overlay {                 if isHovering {                     Text("x: \(hoverLocation.x), y: \(hoverLocation.y)")                         .foregroundColor(.white)                         .font(.title)                 }             }     } }

Мы увидим, что текст сообщает координаты и указателя в локальном координатном пространстве view RoundedRectangle.

local (локальное) координатное пространство используется по умолчанию для onContinuousHover(perform:). При необходимости мы можем указать global (глобальное) или named (именованное) пространство.

Добавляем круг в месте указателя

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

struct ContentView: View {     @State private var hoverLocation: CGPoint = .zero     @State private var isHovering = false          var body: some View {         RoundedRectangle(cornerRadius: 20, style: .continuous)             .fill(.indigo)             .frame(width: 400, height: 300)             .onContinuousHover { phase in                 switch phase {                 case .active(let location):                     hoverLocation = location                     isHovering = true                 case .ended:                     isHovering = false                 }             }             .overlay {                 if isHovering {                     Circle()                         .fill(.white)                         .opacity(0.5)                         .frame(width: 30, height: 30)                         .position(x: hoverLocation.x, y: hoverLocation.y)                 }             }     } }

Обратите внимание: поскольку мы помещаем круг в наложение прямоугольника со скругленными углами, мы можем просто использовать координаты наведения, данные нам в локальном пространстве координат прямоугольника. В других случаях может потребоваться использовать глобальное координатное пространство или указать именованное.

Связанные посты

· Adjust the direction of focus-based navigation in SwiftUI

· Programmatically open a new window in SwiftUI on macOS

· Detect focused window on macOS

· Get tap location in SwiftUI

Если вам нравится наш блог и вы хотите поддержать нас, вы можете спонсировать нас на GitHub.

Чтобы получать новости о блоге и советы по разработке, следите за нами в Твиттере.


ссылка на оригинал статьи https://habr.com/ru/post/718542/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *