Какое-то время у нас был только модификатор 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) } } } }
Мы увидим, что текст сообщает координаты x и y указателя в локальном координатном пространстве 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
Если вам нравится наш блог и вы хотите поддержать нас, вы можете спонсировать нас на GitHub.
Чтобы получать новости о блоге и советы по разработке, следите за нами в Твиттере.
ссылка на оригинал статьи https://habr.com/ru/post/718542/
Добавить комментарий