如何在 SwiftUI 中结合可折叠行使用 List 自定义行内部内容?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中结合可折叠行使用 List 自定义行内部内容?【英文标题】:How to customize row internal content with List in SwiftUI combining collapsable rows? 【发布时间】:2020-09-06 22:05:39 【问题描述】:这是topic的后续问题。
如何将行内的“Hello World”卡片固定到其单元格的顶部?当第二张卡片通过点击出来时它不应该移动。
当前状态:
但在行单元格内,它应该与其顶部对齐,就像这张图片中所描绘的那样:
struct ContentView: View
var body: some View
VStack
Text("Hello!")
List
Detail(isExpanded: false)
Detail(isExpanded: false)
Detail(isExpanded: false)
struct Detail: View
@State var isExpanded :Bool = false
var body: some View
VStack
ZStack (alignment: .bottom)
ZStack (alignment: .center)
RoundedRectangle(cornerRadius: 8)
.fill(Color(red: 0.0, green: 1.0, blue: 1.0, opacity: 0.5)).frame(height: 115)
Text("Helloo!")
.zIndex(3).frame(height: 115).contentShape(Rectangle()).onTapGesture
withAnimation (.linear(duration: 0.1))
self.isExpanded.toggle()
Button(action:
)
ZStack
RoundedRectangle(cornerRadius: 50)
.fill(Color(red: 1.0, green: 0.0, blue: 1.0, opacity: 0.5)).frame(height: 70)
.cornerRadius(8)
.shadow(radius: 3)
Text("Test")
.padding([.leading, .trailing], 12)
//.padding(.top, 6)
.frame(height: 70)
.buttonStyle(BorderlessButtonStyle())
.offset(y: self.isExpanded ? 80 : 0)
.disabled(!self.isExpanded)
if(self.isExpanded)
Spacer()
.modifier(AnimatingCellHeight(height: self.isExpanded ? 210 : 115)).background(Color(red: 1.0, green: 0.5, blue: 1, opacity: 0.5))
struct AnimatingCellHeight: AnimatableModifier
var height: CGFloat = 0
var animatableData: CGFloat
get height
set height = newValue
func body(content: Content) -> some View
content.frame(height: height)
编辑
最终结果应该是这样的。倒置的 isExpanded Bool 是我的错……应该反过来。
EDIT 2 上面的代码已更新为最新尝试。您将在下面的 gif 中看到。
差不多到了....在下面的 gif 中,我按下展开的蓝色卡片正在上下移动一点(当增加点击频率时您可以清楚地看到)。否则行为是完美的,只是卡应该上下摆动......
【问题讨论】:
好吧,实际上至于最后应该实现什么还不清楚(还有那个 inverted "isExpanded" 标志让我感到困惑)。是否应该将所有内容都移到顶部(那为什么下面有空闲空间)?你好按钮是否应该调整到顶部?新布局在动画上应该如何表现?等等......因为对您的要求的严格理解导致了克里斯在下面提出的建议(我的第一次尝试是相同的,但我不喜欢出现的内容)。 倒旗是我的错。你说得对。但我添加了我想要实现的截图。从概念的角度来看,克里斯非常接近。但是蓝色的卡片在点击时会上下移动一点。它应该保持稳定而不移动。下面的第二个视图应该移到“Hello!”下面。卡片(如图所示)。 【参考方案1】:你是这个意思吗? (添加 VStack + Spacer)
struct Detail: View
@State var isExpanded :Bool = false
var body: some View
VStack
ZStack
ZStack
RoundedRectangle(cornerRadius: 8)
.fill(Color(red: 0.0, green: 1.0, blue: 1.0, opacity: 1.0)).frame(height: 115)
Text("Hello!")
.zIndex(3).frame(height: 115).contentShape(Rectangle()).onTapGesture
withAnimation
self.isExpanded.toggle()
Button(action:
)
ZStack
RoundedRectangle(cornerRadius: 50)
.fill(Color(red: 1.0, green: 0.0, blue: 1.0, opacity: 1.0)).frame(height: 70)
.cornerRadius(8)
.shadow(radius: 3)
Text("Test")
.padding([.leading, .trailing], 12)
.padding(.top, 6)
.frame(height: 70)
.buttonStyle(BorderlessButtonStyle())
.offset(y: self.isExpanded ? 0 : 40)
.disabled(!self.isExpanded)
Spacer()
.modifier(AnimatingCellHeight(height: self.isExpanded ? 120 : 200))
【讨论】:
非常接近。当你点击“你好!” “你好!” rect 上下移动 2 点。它应该保持完全稳定而不移动。只有紫色视图应该移动。剩余的列表当然可以移动,因为占用了更多空间。除此之外。这就是我想要实现的目标。 我还在帖子中添加了我想要实现的目标的屏幕截图。但是,如果您知道如何保持卡片稳定,我会接受答案。我可以处理剩下的。我只需要它如何工作的概念。 我正忙于类似的事情,有同样的问题。它在跳跃。我想知道这是否是有意为之的;一种(失败的)字符串效果?如果不是故意的,你解决了吗? BTW,我用的不是List,但是效果差不多,只是稍微动了动。是否使用和不使用 List 容器进行了测试:(以上是关于如何在 SwiftUI 中结合可折叠行使用 List 自定义行内部内容?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不实际删除行的情况下明显折叠 Silverlight 4 ListBox 中的单行?