【问题标题】:StackView layout side by side & on Top of each other (like zStack)StackView 布局并排并在彼此之上(如 zStack)
【发布时间】:2021-01-07 12:35:36
【问题描述】:

我目前有这个界面,我将 MapView 和 UIView 放在一起。 UIView 是我放置图表叠加层的位置(例如:心率)。

当设备处于纵向模式时,这很好。但是,我想在横向模式下探索一种不同的布局,即 UIView(HR Chart) 和 MapView 并排。

这在 Interface Builder 中可行吗?还是仅在代码中? (我只想使用 UIKit 更好地支持较低的操作系统)

注意:我在 IB 中尝试过,但似乎无法弄清楚如何获取 Stack 以使 MapView 和 UIView 在纵向模式下相互重叠。

这就是现在的样子。但我想在横向模式下并排显示图表和地图。

编辑以澄清纵向模式下的当前布局和横向模式下的预期结果。 布局的样子。

【问题讨论】:

    标签: ios swift swiftui uistackview


    【解决方案1】:

    这可以通过在堆栈视图上使用特征变化来完成,在垂直和水平之间更改轴。

    考虑一下这个布局 - 我给标签设置了背景颜色来帮助可视化:

    • 每个“名称/值”标签集都位于垂直堆栈视图中
    • “组”中的每个“对” - 功率/斜率、距离/经过时间、心率/节奏 - 也在各自的垂直堆栈视图中
    • 这 3 个“对”位于水平堆栈视图中

    选择RedPairStack,然后在“属性检查器”窗格中,单击轴左侧的+ 图标:

    从该弹出窗口中,将 Width 更改为 Any 并将 Height 更改为 Compact 并单击 Add Variation

    对于新的hC 变体,选择Horizontal

    GreenPairStackBluePairStack 执行相同操作。

    现在,当设备具有常规高度时,这三个堆栈视图将使用垂直轴...在紧凑高度中,它们将使用水平轴。

    结果如下:

    这里是 Storyboard 的来源,因此您可以检查所有内容:https://pastebin.com/dqNp8CcC


    编辑 - 在 cmets...

    要实现并排,我们需要进行一些更改:

    看起来很相似,但是:

    • UIView - “PairsContainerView”(哈密瓜背景)中嵌入了“标签/值”水平堆栈
    • 将该视图和地图视图嵌入垂直堆栈视图中

    我从 PairStacks 中删除了 Trait 变体,然后将 Horizo​​ntalStack 约束到“PairsContainerView”的所有 4 个边

    结果起初看起来不错,但旋转时标签会被拉长。因此,我们添加了几个新的特征变化。

    首先,将所有标签的 Content Hugging Priority 设置为Required。

    接下来,对于 Compact Height (hC) 特征,我们将 CenterY 约束添加到 Horizo​​ntalStack,并移除 Top 和 Bottom 约束。

    以下是新结果:

    并去除颜色:

    由于您没有提供您希望布局外观的图片,这可能足以让您上路。

    新故事板源:https://pastebin.com/TkVbNUVE


    编辑 2

    从上面的第一个例子开始...

    添加一个UIView 作为地图视图的同级并将其自定义类分配给HeartRateView

    这是我的快速HeartRateView(红色波浪线):

    class HeartRateView: UIView {
    
        let shapeLayer = CAShapeLayer()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            commonInit()
        }
        
        func commonInit() -> Void {
            layer.addSublayer(shapeLayer)
            shapeLayer.strokeColor = UIColor.red.cgColor
            shapeLayer.fillColor = UIColor.clear.cgColor
            shapeLayer.lineWidth = 1.0
    
            let pth = UIBezierPath()
            let topY: CGFloat = 40.0
            var pt: CGPoint = CGPoint(x: 0.0, y: topY)
            pth.move(to: pt)
            for _ in 1...30 {
                pt.x += 2
                pt.y = topY + CGFloat.random(in: 0...40)
                pth.addLine(to: pt)
            }
            
            shapeLayer.path = pth.cgPath
        }
    
    }
    

    将这些约束添加到 HeartRateView:

    • 顶部等于 MapView 顶部
    • 前导等于 MapView 前导
    • 宽度等于 MapView 宽度
    • 高度等于 MapView 高度

    如您所料,这将“叠加”在 MapView 上的 HeartRateView。

    现在,在 Storyboard 中,将 Orientation 切换为 Landscape,然后单击“Vary for Traits”按钮。从该弹出窗口中,选择Height

    在 Document Outline 窗格中选择 MapView,然后在 Size Inspector 窗格中选择 Trailing to Safe Area 和 Leading to Heart Rate View 约束:

    点击键盘上的删除 - 它会删除此 Trait 变体的那些约束。应该是这样的:

    你的视图应该是这样的:

    选择心率视图并将其尾随限制到安全区域(我在所有内容上都使用 4 点填充)。您的视图现在应该如下所示(心率视图有清晰的背景,所以我们只能看到选择句柄):

    现在添加一个从 MapView Trailing 到 HeartRateView Leading 的约束(小填充为 4):

    因为 HeartRateView 仍然被限制为 MapView 的 Equal Width,所以它们会自动填充宽度。

    最后一步,点击完成变化

    现在我们得到这个输出:

    这是第三个故事板来源:https://pastebin.com/2hPXisAH

    【讨论】:

    • OP想要实现横向并排的布局,所以我认为地图应该在屏幕的右侧,仪表盘在屏幕的左侧。
    • @donMag 首先。非常令人印象深刻。我花了几天时间才在横向模式下将功率/斜率等设置为 1 行)正确。 (我对 IB 的仇恨越来越大:-p)。第二,我很抱歉(如果)你花了这么多时间,但我实际上希望“mapView”和“UIView”在横向模式下并排。 (也许而且很可能我的描述不是那么好)。在纵向模式下,MapView 和 UIView(带有 HR 图表)彼此重叠。在横向模式下,我想探索它们并排..(注意:我没有看过你的源代码)
    • @myjunk - 啊,以为你在展示你想要的布局。请参阅我的答案的编辑。
    • @DonMag - 当我描述心率图 (Uiview) 位于 MapView 顶部(如 zstack)时,我添加了视图的外观图片。 UIView 是透明的,可以绘制用户的心率数据(屏幕截图上那些波浪状的红线)。它与地图视图的大小完全相同。我添加了一个侧视图来显示当前布局。 ?抱歉给您带来了困惑。
    • @myjunk - 如果您仍在尝试使此布局正常工作...一般的想法是为 HeartRateView 创建 2 个主要约束:一个用于地图可见,一个用于隐藏地图。当地图可见时将“MapVisible”约束设置为更高的优先级,当地图隐藏时将“MapHidden”约束设置为更高的优先级。我在这里放了一个更新的 Storyboard 和相关的 View Controller 代码:gist.github.com/DonMag/1ddc83e04584756ad750855b16a14ba1
    猜你喜欢
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多