SwiftUI - 披露组扩展行为 - 保持顶部项目静态

Posted

技术标签:

【中文标题】SwiftUI - 披露组扩展行为 - 保持顶部项目静态【英文标题】:SwiftUI - disclosure group expanding behaviour - keep top item static 【发布时间】:2020-12-07 11:57:11 【问题描述】:

我正在尝试使用 swift UI 创建一个下拉菜单。我实际上正在将它实现到 UIKit 项目中。

我要实现的基本功能应该是用户单击带有特定数据单位的标签,然后列表扩展为可以选择的其他度量单位。

这是我的 SwiftUI 代码:

import SwiftUI

@available(ios 14.0.0, *)
struct DataUnitDropDown: View 
    var units = ["ltr", "usg", "impg"]
    
    @State private var selectedDataUnit = 0
    @State private var isExpanded = false
    
    var body: some View 
        VStack(alignment: .leading, spacing: 15) 
            DisclosureGroup(units[selectedDataUnit], isExpanded: $isExpanded) 
                VStack 
                    ForEach(0 ..< units.count, id: \.self)  index in
                        Text("\(units[index])")
                            .font(.title3)
                            .padding(.all)
                            .onTapGesture 
                                self.selectedDataUnit = index
                                withAnimation 
                                    self.isExpanded.toggle()
                                
                            
                        
                    
                
            
        
    

所以我在这里有几个问题。首先,理想情况下,我想将其放入现有的水平 UIStackView 中。但是,我遇到的问题是,一旦下拉列表扩展,它就会增加堆栈的高度,这不是我想要的。这是组件的屏幕截图(参见“ltr”):

在stackView中展开时:

所以我不情愿地将它放在主视图中,添加了一些自动布局约束:

    if #available(iOS 14.0.0, *) 
        let controller = UIHostingController(rootView: DataUnitDropDown())
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        addSubview(controller.view)
        controller.view.leadingAnchor.constraint(equalTo: refuelInfoView.actualUpliftVolume.trailingAnchor).isActive = true
        controller.view.centerYAnchor.constraint(equalTo: refuelInfoView.actualUpliftVolume.centerYAnchor).isActive = true
    

但是现在当我展开时,整个菜单会向上移动:

显然不是我想要的。

所以我想我的问题是 2 倍的:

1- 有什么方法可以将此元素合并到现有的堆栈视图中,而不会在展开下拉列表时增加堆栈的高度? (我猜不是!)

2- 如果我必须将它添加到主视图而不是堆栈,我如何才能阻止整个菜单在展开时向上移动?

更新:

我将代码修改如下:

 if #available(iOS 14.0.0, *) 
        let controller = UIHostingController(rootView: DataUnitDropDown())
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        controller.view.clipsToBounds = false
        controller.view.heightAnchor.constraint(equalToConstant: 22).isActive = true
        controller.view.topAnchor.constraint(equalTo: topAnchor).isActive = true
        stackSubviews = [inputField, controller.view]
    

现在,如果没有 topAnchor 约束,这可以完美地工作,但我确实需要这个约束。但由于意见,我得到一个错误。不在同一层次中

【问题讨论】:

【参考方案1】:

我假设不是

controller.view.centerYAnchor.constraint(equalTo: 
       refuelInfoView.actualUpliftVolume.centerYAnchor).isActive = true

你需要

controller.view.topAnchor.constraint(equalTo: 
       refuelInfoView.actualUpliftVolume.bottomAnchor).isActive = true

【讨论】:

是的,你是绝对正确的,这是多么愚蠢的错误:/ 你会知道是否有任何可行的方法可以将其添加到堆栈视图而不影响扩展时堆栈的高度?我想知道以某种方式使用叠加层,但无法弄清楚 尝试以所需的优先级修复高度约束并将clipsToBounds设置为false,因此注入的下拉视图将可见...但是不确定它是否适用于所有情况,您会看到任何类型的系统menu (context, popup) 是原始视图之外的问题。 啊哈,到了。所以我更新了上面的帖子。它非常接近工作,但我现在遇到的问题是我无法将其固定到当前视图的约束,因为我得到一个错误,不在同一个层次结构中,令人沮丧!

以上是关于SwiftUI - 披露组扩展行为 - 保持顶部项目静态的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - tvOS 上的列表 - 顶部渐变

在添加和删除第二个按钮时保持 SwiftUI 中的导航项按钮对齐

Swiftui 隐藏披露箭头

没有 NavigationLink 的 SwiftUI 列表披露指示器

SwiftUI:滚动视图中的顶部锚定可调整大小视图

SwiftUI .onTapGesture 从未调用过