什么是iOS';s相当于Java/Swing';什么是流程布局?

什么是iOS';s相当于Java/Swing';什么是流程布局?,ios,cocoa-touch,layout,uiview,flowlayout,Ios,Cocoa Touch,Layout,Uiview,Flowlayout,我正在尝试构建一个UIView,该视图使用其他视图的固有宽度(从左到右)来布局其他视图,然后在必要时进行换行UICollectionView对于我所需要的内容来说似乎过于复杂。我还试着用FlexLayout包装来做瑜伽,但似乎找不到正确的咒语。看起来应该比这简单得多——简单的解决方案是什么?在interface builder中,使用UIStackView实现简单的替代方案 您还可以启用自动布局以使其自然。我最终编写了自己的UIView来解决这个问题。我怀疑它是否非常健壮,但它解决了我的迫切需要

我正在尝试构建一个
UIView
,该视图使用其他视图的固有宽度(从左到右)来布局其他视图,然后在必要时进行换行<代码>UICollectionView对于我所需要的内容来说似乎过于复杂。我还试着用FlexLayout包装来做瑜伽,但似乎找不到正确的咒语。看起来应该比这简单得多——简单的解决方案是什么?

在interface builder中,使用UIStackView实现简单的替代方案


您还可以启用自动布局以使其自然。

我最终编写了自己的UIView来解决这个问题。我怀疑它是否非常健壮,但它解决了我的迫切需要。如果您有改进建议,请发表评论

import UIKit

class FlowLayout: UIView {
private var hgapValue: CGFloat = 0.0
private var vgapValue: CGFloat = 0.0

var hgap: CGFloat {
    set(newValue) {
        hgapValue = (newValue < 0) ? -newValue : newValue
    }
    get {
        return hgapValue
    }
}

var vgap: CGFloat {
    set(newValue) {
        vgapValue = (newValue < 0) ? -newValue : newValue
    }
    get {
        return vgapValue
    }
}

//initWithFrame to init view from code
override init(frame: CGRect) {
    super.init(frame: frame)
    setupView()
}

//initWithCode to init view from xib or storyboard
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupView()
}

override func didAddSubview(_ subview: UIView) {
    refreshLayout()
}

//common func to init our view
private func setupView() {
    // backgroundColor = .red
}

public func refreshLayout() {
    var x: CGFloat = 0.0
    var y: CGFloat = 0.0

    for subview in subviews {
        subview.frame.origin.x = x
        subview.frame.origin.y = y
        x += subview.frame.width + hgapValue
        if x + subview.frame.width >= (subview.superview?.frame.width)! {
            x = 0.0
            y += subview.frame.height + vgapValue
        }

    }
    setNeedsDisplay()
}

}
导入UIKit
类FlowLayout:UIView{
私有var hgapValue:CGFloat=0.0
私有var vgapValue:CGFloat=0.0
var hgap:CGFloat{
设置(新值){
hgapValue=(newValue<0)?-newValue:newValue
}
得到{
返回hgapValue
}
}
var vgap:CGFloat{
设置(新值){
vgapValue=(newValue<0)?-newValue:newValue
}
得到{
返回vgapValue
}
}
//initWithFrame从代码到init视图
重写初始化(帧:CGRect){
super.init(frame:frame)
setupView()
}
//initWithCode从xib或故事板初始化视图
必需的初始化?(编码器aDecoder:NSCoder){
super.init(编码者:aDecoder)
setupView()
}
重写func didAddSubview(subview:UIView){
刷新布局()
}
//公共函数初始化我们的视图
私有函数设置视图(){
//背景颜色=.red
}
公共函数刷新布局(){
变量x:CGFloat=0.0
变量y:CGFloat=0.0
用于子视图中的子视图{
子视图.frame.origin.x=x
子视图.frame.origin.y=y
x+=子视图.frame.width+hgapValue
如果x+subview.frame.width>=(subview.superview?.frame.width){
x=0.0
y+=子视图.frame.height+vgapValue
}
}
setNeedsDisplay()
}
}

除了第一句话中的要求外,还有其他要求吗?您提供的详细信息越多,就越有可能有人只知道iOS就能够回答这个问题(也就是说,不必了解FlowLayout)。没有其他要求。使用固有宽度和包装是核心要求。我需要添加/删除子视图,因此它应该在添加/删除视图时根据需要多次包装/展开。您的意思是,在视图显示在屏幕上时动态添加/删除它们?是的。我会看看我是否可以上传一个我想要构建的屏幕截图,但是这个想法非常简单。用户在屏幕底部的1-12复选框之间进行选中,将相应的图像添加到屏幕顶部。当然,他可能会改变他想看什么的想法,所以他可能会多次勾选和取消勾选。上屏幕自然保持最新状态。最后按下一个按钮,图像被随机重新排序。这段视频的前25秒让你知道我在尝试做什么,尽管它没有显示meeple形状的图像包装,当选择的图像超过适合的数量时。请记住,
UIStackView
让您设置一列或一行控件。很遗憾,它与Swing的FlowLayout或集合视图的flow layout完全不同。UIStackView没有包装。关于嵌套堆栈视图