Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why custom views in stack view are overlapping?

I'm trying to create a stack view with custom views inside. Each custom view in this example has the same information. For some reason instead of going each after each the subviews are overlapping and I can't figure out why. I don't have any constraints (in the layout). The stack view is inside scroll view because there may be many subviews.

The code of custom view:

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)
}

}

Here is how I dynamically add subviews (viewContent is stack view):

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)

And here is awful result:

crap

That's what happened if I add 30 subviews:

enter image description here

That's what happened if I add 30 subviews:

Another thing that is very strange is the fact that I make the background custom view blue, and set it opaque and these properties are being ignored for some reason. That is how the component looks in the design time: Now I'm trying to add these subviews into Prototype cell of 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
}

This code is very stupid, I just experimented with different views (I created 2 custom views). Both of them have approx same code:

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 is the view that I put into Prototype cell.

like image 997
mimic Avatar asked Dec 10 '16 05:12

mimic


People also ask

Do stack views have intrinsic content size?

Stack views don't have an intrinsic content size, so you must set it either implicitly with Auto Layout constraints or explicitly via its intrinsicContentSize property.

How do I use views in stack?

Position the label and text field in their correct relative positions, select them both, and then click the Editor > Embed In > Stack View menu item. This creates a horizontal stack view for the row. Next, position these rows horizontally, select them, and click the Editor > Embed In > Stack View menu item again.

How do I stack views in Swift?

To use a stack view, open the Storyboard you wish to edit. Drag either a Horizontal Stack View or a Vertical Stack View out from the Object library, and position the stack view where desired. Next, drag out the stack's content, dropping the view or control into the stack.

What is stack view?

Stack View Appearance The property that determines how a stack view lays out its subviews along its axis is distribution . Currently, it's set to Fill , which means the subviews will completely fill the stack view along its axis.


2 Answers

Problem is that UIStackView row does not know height of UIStackView, try to set height of that view or maybe change distribution property of UIStackView. Why are you now user UITableView for this, this looks like perfect example to use UITableView, than you would no need UIScrollView?

like image 196
Markicevic Avatar answered Sep 29 '22 10:09

Markicevic


Try to override intrinsicContentSize of your custom view. The stack view will know then the height of arranged subview.

like image 40
Nik Kov Avatar answered Sep 29 '22 12:09

Nik Kov