【发布时间】:2021-03-04 06:24:29
【问题描述】:
我需要有关 SwiftUI 动画/过渡行为的帮助。在将 lineLimit 从 nil 更改为 5 期间,我必须实现折叠/扩展 Text,反之亦然。
目前我有一个工作代码,你可以在下面看到它。
import SwiftUI
public struct ContentView: View {
private let description: String
@State private var isCollapsed: Bool = true
@State private var isExpandeButtonShow: Bool = false
public init(description: String) {
self.description = description
}
// MARK: - Body
public var body: some View {
VStack(alignment: .leading, spacing: 0) {
text.padding(.top, 26)
.font(Font.system(size: 12))
if isExpandeButtonShow {
collapseButton.padding(.top, 9)
}
Spacer()
}
.padding(.horizontal, 16)
}
// MARK: - Private
private var text: some View {
Text(description)
.lineLimit(isCollapsed ? 5 : nil)
.background(
GeometryReader { geometry in
Color.clear.onAppear {
truncateIfNeeded(withGeometry: geometry)
}
}
)
.animation(.linear(duration: 4))
.transition(.opacity)
}
private func truncateIfNeeded(withGeometry geometry: GeometryProxy) {
let total = description.boundingRect(
with: CGSize(
width: geometry.size.width,
height: .greatestFiniteMagnitude
),
options: .usesLineFragmentOrigin,
attributes: [.font: UIFont.systemFont(ofSize: 12)],
context: nil
)
if total.size.height > geometry.size.height {
isExpandeButtonShow = true
}
}
private var collapseButton: some View {
button(title: collapseButtonTitle()) {
isCollapsed.toggle()
}
}
private func button(title: String, handler: @escaping () -> Void) -> some View {
Button(action: handler) {
Text(title)
.foregroundColor(Color.blue)
.contentShape(Rectangle())
}
.buttonStyle(PlainButtonStyle())
}
private func collapseButtonTitle() -> String {
isCollapsed ? "Collapse" : "Expand"
}
}
它几乎可以满足我的要求。但是这种行为让我有两点痛苦。 首先,当我尝试折叠文本时,没有动画/过渡开始。它只是立即崩溃。其次,我想让一条线逐行出现,每条线的不透明度从 0 变为 1。我该怎么做?
任何想法都会有所帮助。问候。
【问题讨论】:
-
“我希望一行一行地出现,每行从 0 不透明度到 1 进行动画处理” - 只有当每一行都在单独的视图中时,才能做到这一点,不在一个文本中。
-
这种行为没有办法实现吗?你确定吗?这听起来完全正确。但我希望 SwiftUI 世界有一个好的解决方法。
标签: ios swift animation swiftui transition