Как применить .onHover к отдельным элементам в SwiftUI - PullRequest
1 голос
/ 05 мая 2020

Я пытаюсь анимировать отдельные элементы при наведении курсора мыши. Проблема, с которой я сталкиваюсь, заключается в том, что каждый элемент анимируется при наведении курсора мыши на элемент, а не только на этот конкретный c элемент. Вот что у меня:

struct ContentView : View {
    @State var hovered = false
    var body: some View {
        VStack(spacing: 90) {
            ForEach(0..<2) {_ in
                HStack(spacing: 90) {
                    ForEach(0..<4) {_ in
                        Circle().fill(Color.red).frame(width: 50, height: 50)
                            .scaleEffect(self.hovered ? 2.0 : 1.0)
                        .animation(.default)
                        .onHover { hover in
                                print("Mouse hover: \(hover)")
                            self.hovered.toggle()
                        }
                    }
                }
            }
        }
        .frame(minWidth:300,maxWidth:.infinity,minHeight:300,maxHeight:.infinity)
    }
}

Рисование

Ответы [ 2 ]

2 голосов
/ 05 мая 2020

Каждый элемент в настоящее время анимируется, потому что все они полагаются на hovered, чтобы увидеть, находится ли Circle над ним. Чтобы исправить это, мы можем сделать так, чтобы каждый круг имел свое состояние hovered.

struct CircleView: View {
    @State var hovered = false

    var body: some View {
        Circle().fill(Color.red).frame(width: 50, height: 50)
            .scaleEffect(self.hovered ? 2.0 : 1.0)
        .animation(.default)
        .onHover { hover in
                print("Mouse hover: \(hover)")
            self.hovered.toggle()
        }
    }
}

, а в ForEach мы можем просто вызвать новый CircleView, где каждый Circle имеет свой собственный источник истины.

struct ContentView : View {
    var body: some View {
        VStack(spacing: 90) {
            ForEach(0..<2) { _ in
                HStack(spacing: 90) {
                    ForEach(0..<4) { _ in
                        CircleView()
                    }
                }
            }
        }
        .frame(minWidth:300,maxWidth:.infinity,minHeight:300,maxHeight:.infinity)
    }
}
2 голосов
/ 05 мая 2020

Необходимо изменить представление onHover для каждого просмотра, ie. сохранить некоторый идентификатор зависшего представления.

Вот возможное решение. Протестировано с Xcode 11.4.

demo

struct TestOnHoverInList : View {
    @State var hovered: (Int, Int) = (-1, -1)
    var body: some View {
        VStack(spacing: 90) {
            ForEach(0..<2) {i in
                HStack(spacing: 90) {
                    ForEach(0..<4) {j in
                        Circle().fill(Color.red).frame(width: 50, height: 50)
                        .scaleEffect(self.hovered == (i,j) ? 2.0 : 1.0)
                        .animation(.default)
                        .onHover { hover in
                            print("Mouse hover: \(hover)")
                            if hover {
                                self.hovered = (i, j)    // << here !!
                            } else {
                                self.hovered = (-1, -1)  // reset
                            }
                        }
                    }
                }
            }
        }
        .frame(minWidth:300,maxWidth:.infinity,minHeight:300,maxHeight:.infinity)
    }
}
...