简体   繁体   English

SwiftUI 如何制作可点击的行和动画文本可见性?

[英]SwiftUI how to make tappable row and animate text visibility?

The code below gives me this:下面的代码给了我这个:

在此处输入图片说明

Tapping the text or arrow rotates the arrow and shows the items.点击文本或箭头可旋转箭头并显示项目。 However I can't tap in the blank space between the text and the image.但是我无法点击文本和图像之间的空白区域。 How can I tap the space area for this to work?我如何点击空间区域才能使其工作? Also, the text shows/hides the items instantaneously.此外,文本会立即显示/隐藏项目。 Is there a way to toggle the showList state only after the animation is complete?有没有办法在动画完成后才切换 showList 状态?

public struct Picker: View {
     @State private var showList = false
     private var iconAngle: Double {
          return showList ? 90 : 0
     }
     private let prompt: String

     public init(promptLocalizationKey: String) {
          self.prompt = NSLocalizedString(promptLocalizationKey, comment: "")
     }

     public var body: some View {
          let tap = TapGesture()
          .onEnded { _ in
                self.showList.toggle()
          }

          return
                VStack {
                     HStack {
                          Text(prompt)
                          Spacer()
                          Image(systemName: "arrow.right.circle.fill")
                                .rotationEffect(.degrees(self.iconAngle))
                                .animation(.linear)
                     }.gesture(tap)
                     if showList {
                          Text("list item 1")
                          Text("list item 2")
                          Text("list item 3")
                     }
                }
     }
}

Depending on your needs you might choose which way of transitioning the two animated UI elements can be better suited for your needs.根据您的需要,您可以选择哪种转换两个动画 UI 元素的方式更适合您的需要。

1) To add an animation through your state changes you just wrap self.showList.toggle() within withAnimation() and to make the hole row or HStack tappable , you treat it as a Rectangle content shape, check this code out. 1) 要通过状态更改添加动画,您只需将self.showList.toggle()包装在withAnimation()中并使孔行或HStack点击,您将其视为矩形内容形状,请查看此代码。

This animates both the text and arrow rotation together at the same moment with a smooth controlled visual effect:该动画both文字和箭头旋转一起at the same moment用光滑控制视觉效果:

public struct Picker: View {
     @State private var showList = false
     private var iconAngle: Double {
          return showList ? 90 : 0
     }
     private let prompt: String

     public init(promptLocalizationKey: String) {
          self.prompt = NSLocalizedString(promptLocalizationKey, comment: "")
     }

     public var body: some View {
          let tap = TapGesture()
          .onEnded { _ in
            withAnimation() {
                self.showList.toggle()
            }
          }

          return
                VStack {
                     HStack {
                          Text(prompt)
                          Spacer()
                          Image(systemName: "arrow.right.circle.fill")
                                .rotationEffect(.degrees(self.iconAngle))
                                .animation(.linear)
                     }
                     .contentShape(Rectangle())
                     .gesture(tap)

                    if showList {
                        Text("list item 1")
                        Text("list item 2")
                        Text("list item 3")
                    }
                }
     }
}

This should be a sample output:这应该是一个示例输出:


2) To animate text visibility after arrow rotation animation through transition , thanks @eduardo for giving another viewpoint on this: 2)为了after箭头旋转动画后通过transition为文本可见性设置动画,感谢@eduardo 对此提供另一个观点:

struct Picker: View {
    @State private var showList = false
    private var iconAngle: Double {
        return showList ? 90 : 0
    }
    private let prompt: String
    public init(promptLocalizationKey: String) {
        self.prompt = NSLocalizedString(promptLocalizationKey, comment: "")
    }
    public var body: some View {
        VStack {
            HStack {
                Text(prompt)
                Spacer()
                Image(systemName: "arrow.right.circle.fill")
                    .rotationEffect(.degrees(self.iconAngle))
                    .animation(.linear)
            }
            .contentShape(Rectangle())
            .gesture(TapGesture()
            .onEnded { _ in
                withAnimation {
                    self.showList.toggle()
                }
            })
            if showList {
                VStack {
                    Text("list item 1")
                    Text("list item 2")
                    Text("list item 3")
                }
                .transition(AnyTransition
                .opacity
                .animation(Animation.linear.delay(0.5)))
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM