ios – Mysterious conduct of stack view with a container view in it: objects previous to a container do not seem

0
36
ios – Mysterious conduct of stack view with a container view in it: objects previous to a container do not seem


Begin a Mac, open Xcode, create a brand new swift-storyboard venture and paste within the demo code under.

Fireplace it up and you will note a jiggly scrollable stack one thing like this ..

stack view container view challenge

All good to this point. Let’s think about the code HERE:

        indentedInner.backgroundColor = .blue // NOTE
        // now add yellow blocks precisely as with "innerYellow" simply above
        for _ in 0..<4 { indentedInner.addArrangedSubview(InBlock()) }

(Discover the indented group is blue inform.)

Now do that!

        indentedInner.backgroundColor = .blue // observe
        // now add yellow blocks precisely as with "innerYellow" simply above
//        for _ in 0..<4 { indentedInner.addArrangedSubview(InBlock()) }
        // no! do not try this! as an alternative let's add a container view
        let vc = InsideStackOfYellowButInAContainer()
        vc.telltale = .purple
        addChild(vc)
        indentedInner.addArrangedSubview(vc.view)
        vc.view.bindEdgesToSuperview()
        vc.didMove(toParent: self)

As you’d anticipate it really works completely, the inform is now the purple of the container’ed VC, every part nonetheless animates, and many others.

BUT…

Subsequent, truly let’s do BOTH:

    indentedInner.backgroundColor = .blue // observe
    // now add yellow blocks precisely as with "innerYellow" simply above
    for _ in 0..<4 { indentedInner.addArrangedSubview(InBlock()) }
    // no! do not try this! as an alternative let's add a container view
    // truly let's do each:
    let vc = InsideStackOfYellowButInAContainer()
    vc.telltale = .purple
    addChild(vc)
    indentedInner.addArrangedSubview(vc.view)
    vc.view.bindEdgesToSuperview()
    vc.didMove(toParent: self)

I should be making some drastic easy mistake, however, as you will note

the “blue” group plain would not seem.

Massive letters added for readability right here.

It appears solely the purple group is current.

I’ve already tried quite a few issues like wrappers, each possible setting, and many others.

One other weird “clue”, strive ALSO including …

    for _ in 0..<4 { indentedInner.addArrangedSubview(InBlock()) }
    let L = UILabel()
    L.textual content = "What the heck"
    indentedInner.addArrangedSubview(L)
    ...

and spot the odd conduct.

I can not remedy the difficulty after the standard hours of fooling with UIKit.

Why does the blue group not seem?


Demo code …

//
//  ViewController.swift
//  testsv
//
//  Created by TV'S FATTIE on 10/6/24.
//

import UIKit

class ViewController: UIViewController {

    var scroll = UIScrollView.Simp
    var high = UIStackView.Simp
    var innerYellow = UIStackView.Simp
    var indentedInner = UIStackView()
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        view.addSubview(scroll)
        scroll.bindEdgesToSuperview()
        scroll.addSubview(high)
        high.bindEdgesToSuperviewVertScrollStyle()
        for _ in 0..<4 { high.addArrangedSubview(Block()) }
        
        // now make a vert stack with 4 of the bouncy yellow blocks:
        high.addArrangedSubview(innerYellow)
        for _ in 0..<4 { innerYellow.addArrangedSubview(InBlock()) }
        // works completely
        
        // now make a hori group, which has one thing on the left...
        let hori = UIStackView.HoriWrapper
        // let's strive these settings for the hori:
        hori.alignment = .fill
        hori.distribution = .fill
        hori.backgroundColor = .inexperienced
        high.addArrangedSubview(hori)
        // this is the one thing on the left ...
        hori.addArrangedSubview(WidthIndent80())
        // the hori then has a stack exactly like "innerYellow" above
        indentedInner.axis = .vertical
        indentedInner.alignment = .fill // observe, or it will not discover the peak
        indentedInner.distribution = .equalSpacing
        indentedInner.spacing = 8
        indentedInner.translatesAutoresizingMaskIntoConstraints = false
        // explicitly equivalent settings to "innerYellow" simply above
        hori.addArrangedSubview(indentedInner)
        indentedInner.backgroundColor = .blue // observe
        // now add yellow blocks precisely as with "innerYellow" simply above
        for _ in 0..<4 { indentedInner.addArrangedSubview(InBlock()) }
        
        // Add extra materials so the general at all times must scroll
        for _ in 0..<20 { high.addArrangedSubview(Block()) }
    }
}

class InsideStackOfYellowButInAContainer: UIViewController {
    var telltale: UIColor?
    var innerYellowButInAContainer = UIStackView.Simp
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        view.translatesAutoresizingMaskIntoConstraints = false // obivously
        view.addSubview(innerYellowButInAContainer)
        innerYellowButInAContainer.bindEdgesToSuperview()
        innerYellowButInAContainer.axis = .vertical
        innerYellowButInAContainer.alignment = .fill
        innerYellowButInAContainer.distribution = .equalSpacing
        innerYellowButInAContainer.spacing = 8
        innerYellowButInAContainer.translatesAutoresizingMaskIntoConstraints = false
        // explicitly equivalent settings to "innerYellow" above
        // add yellow blocks precisely as with "innerYellow" above
        for _ in 0..<4 { innerYellowButInAContainer.addArrangedSubview(InBlock()) }
        
        innerYellowButInAContainer.backgroundColor = telltale
    }
}

class Block: UIView {
    override var intrinsicContentSize: CGSize {
        backgroundColor = .systemPink.jigglingHue()
        var sz = tremendous.intrinsicContentSize
        sz.top = 40
        return sz
    }
}
class InBlock: UIView {
    override var intrinsicContentSize: CGSize {
        delay(CGFloat.random(in: 3.0...3.5)) {
            self.invalidateIntrinsicContentSize()
        }
        backgroundColor = .systemYellow.jigglingHue()
        var sz = tremendous.intrinsicContentSize
        sz.top = CGFloat.random(in: 50...100)
        return sz
    }
}
extension UIScrollView {
    static var Simp: UIScrollView {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.bounces = true
        return v
    }
}
extension UIStackView {
    static var Simp: UIStackView {
        let v = UIStackView()
        v.axis = .vertical
        v.alignment = .fill
        v.distribution = .equalSpacing
        v.spacing = 8
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }
}
extension UIStackView {
    static var HoriWrapper: UIStackView {
        let v = UIStackView()
        v.axis = .horizontal
        v.spacing = 8
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }
}
class WidthIndent80: UIView {
    override var intrinsicContentSize: CGSize {
        backgroundColor = .lightGray
        var sz = tremendous.intrinsicContentSize
        sz.width = 80
        return sz
    }
}
extension UIView {
    public func bindEdgesToSuperview() {
        guard let s = superview else {
            preconditionFailure("`superview` nil in bindEdgesToSuperview")
        }
        translatesAutoresizingMaskIntoConstraints = false
        leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
        trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
        topAnchor.constraint(equalTo: s.topAnchor).isActive = true
        bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true
    }
    public func bindEdgesToSuperviewVertScrollStyle() {
        guard let s = superview else {
            preconditionFailure("`superview` nil in bindEdgesToSuperview")
        }
        translatesAutoresizingMaskIntoConstraints = false
        leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
        trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
        topAnchor.constraint(equalTo: s.topAnchor).isActive = true
        bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true
        widthAnchor.constraint(equalTo: s.widthAnchor).isActive = true
    }
    public func bindTopToSuperview() {
        guard let s = superview else {
            preconditionFailure("`superview` nil in bindEdgesToSuperview")
        }
        translatesAutoresizingMaskIntoConstraints = false
        leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
        trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
        topAnchor.constraint(equalTo: s.topAnchor).isActive = true
    }
}
extension UIColor {
    func jigglingHue() -> UIColor {
        var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        guard self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) else { return self }
        var jiggle = h + CGFloat.random(in: -0.04...0.04)
        whereas jiggle < 0 { jiggle += 1.0 }
        whereas jiggle >= 1 { jiggle -= 1.0 }
        return UIColor(hue: jiggle, saturation: s, brightness: b, alpha: a)
    }
}
public func delay(_ delay:Double, closure:@escaping () -> ()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.principal.asyncAfter(deadline: when, execute: closure)
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here