为啥堆栈视图中的自定义视图重叠?

Posted

技术标签:

【中文标题】为啥堆栈视图中的自定义视图重叠?【英文标题】:Why custom views in stack view are overlapping?为什么堆栈视图中的自定义视图重叠? 【发布时间】:2016-12-10 05:54:06 【问题描述】:

我正在尝试创建一个内部包含自定义视图的堆栈视图。此示例中的每个自定义视图都具有相同的信息。由于某种原因,每个子视图都重叠,而不是每个都去,我不知道为什么。我没有任何限制(在布局中)。堆栈视图在滚动视图内,因为可能有很多子视图。

自定义视图代码:

import UIKit

class AddressComponentView: UIView 

    @IBOutlet weak var labelStreet: UILabel!
@IBOutlet weak var labelCity: UILabel!
@IBOutlet weak var labelOfficialRegionType: UILabel!
@IBOutlet weak var labelOfficialRegionTitle: UILabel!
@IBOutlet weak var labelCountry: UILabel!
@IBOutlet weak var labelZip: UILabel!

var view: UIView!

func loadData(address: AddressData)
    self.labelStreet.text = address.street
    self.labelCity.text = address.city
    self.labelOfficialRegionType.text = address.region?.officialRegionType
    self.labelOfficialRegionTitle.text = address.region?.officialRegionTitle
    self.labelZip.text = address.zip
    self.labelStreet.sizeToFit()


override init(frame: CGRect) 
    super.init(frame: frame)


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)

这是我如何动态添加子视图(viewContent 是堆栈视图):

viewScroll.contentSize = CGSize(width: 320, height: 1000)

            let viewsDictionary = ["stackView":viewContent]
            let stackView_H = NSLayoutConstraint.constraints(
                withVisualFormat: "H:|-20-[stackView]-20-|",  //horizontal constraint 20 points from left and right side
                options: NSLayoutFormatOptions(rawValue: 0),
                metrics: nil,
                views: viewsDictionary)
            let stackView_V = NSLayoutConstraint.constraints(
                withVisualFormat: "V:|-30-[stackView]-30-|", //vertical constraint 30 points from top and bottom
                options: NSLayoutFormatOptions(rawValue:0),
                metrics: nil,
                views: viewsDictionary)
            view.addConstraints(stackView_H)
            view.addConstraints(stackView_V)


let addressView = UINib(nibName: "AddressComponent", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! AddressComponentView

addressView.loadData(address: (item?.addressData)!)
viewContent.addArrangedSubview(addressView)

let addressView1 = UINib(nibName: "AddressComponent", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! AddressComponentView

addressView1.loadData(address: (item?.addressData)!) viewContent.addArrangedSubview(addressView1)

这是一个糟糕的结果:

如果我添加 30 个子视图,就会发生这种情况:

另一件非常奇怪的事情是,我将背景自定义视图设置为蓝色,并将其设置为不透明,并且由于某种原因这些属性被忽略了。这就是组件在设计时的样子: 现在我正在尝试将这些子视图添加到 UITableView 的原型单元中:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    if indexPath.row == 3 || indexPath.row == 7 
        var text = "Run the app again, and it will look nothing has really changed. You are now using your bioLabel, but it’s just showing one line of text in each cell. Even though the number of lines is set to 0 and your constraints are properly configured so your bioLabel takes up"

        let customView1 = UINib(nibName: "CustomView1", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomView1
        customView1.frame = CGRect(x:0, y:0, width: 200, height: 60)
        customView1.loadData(text: text)
        cell.container.addSubview(customView1)
     else 
        let customView2 = UINib(nibName: "CustomView2", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomView2

        customView2.loadData(text: "aaaaa adfsd")
        cell.container.addSubview(customView2)

    

    // Configure the cell...

    return cell

这段代码非常愚蠢,我只是尝试了不同的视图(我创建了 2 个自定义视图)。他们都有大约相同的代码:

class CustomView1: UIView 

@IBOutlet weak var label1: UILabel!

func loadData(text: String)
    label1.text = text

override init(frame: CGRect) 
    super.init(frame: frame)


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)

NB cell.container 是我放入原型单元格的视图。

【问题讨论】:

你能发布如果你放 3-4 个 AddressComponent 的结果会怎样,也许它超出了堆栈视图的边界,也许你必须限制 AddressComponent 的高度,以便堆栈视图现在可以有多大它应该是行。 @Markicevic,感谢您的回复。我在帖子中添加了更多图片。很抱歉把 cmets 弄得一团糟,我不知道如何正确放置它们,但你现在应该能明白了。我添加了 30 次观看。 【参考方案1】:

问题是 UIStackView 行不知道 UIStackView 的高度,尝试设置该视图的高度或者更改 UIStackView 的分布属性。 为什么你现在为此使用 UITableView,这看起来像是使用 UITableView 的完美示例,而不是你不需要 UIScrollView?

【讨论】:

如果我设置了堆栈视图的高度,它不会显示任何内容。我不知道我对这个容器的选择可能是错误的。据我了解,我需要一些允许逐个添加项目的容器,但我没有考虑到 stackview 可能 总是试图均匀地分配内容。我要添加的子视图的高度根本不相等,而且我事先不知道将添加哪些视图(它基于对象的属性)。 UITableView 是否允许添加不相等的项目? 对 uitableview 和 uicollectionview 进行一些谷歌搜索,我想你会在本教程中找到你需要的。 看起来这个动态表正是我所需要的。非常感谢(老实说,我搜索了很多,但可能我使用了错误的关键字,因为我找不到任何东西)。谢谢!请注意,一旦我完成此示例,我会尽快检查您的答案作为解决方案。 很高兴我能帮上忙 ? 请看一些 tableview 教程,你所做的是在 viewDidLoad register class(xib) 上为 table view 和 cellForRowAt 你不从 xib 创建视图,你从 table view 中重用一个,是表格视图的一个点,要重用单元格并且只是为了拥有不同的数据,您可以为表格视图注册多个类(xib),然后在重用时选择要重用于该行的女巫。这就是你应该这样做的方式,你只需要对表格视图进行一些研究。 :)【参考方案2】:

尝试覆盖您的自定义视图的intrinsicContentSize。堆栈视图将知道排列的子视图的高度。

【讨论】:

以上是关于为啥堆栈视图中的自定义视图重叠?的主要内容,如果未能解决你的问题,请参考以下文章

在 xcode 中的自定义视图中给出高度后刷新情节提要视图控制器

如何用不同的 Xib 替换我的自定义视图

故事板中的自定义 UIView

重叠视图中的 ios 手势识别器

为啥 Android Studio 设计器显示我的自定义视图嵌套在自身内部,而它不是

IOS 为啥一个视图有2个自定义类?