简体   繁体   English

以编程方式清空 UIStackView

[英]Programmatically emptying UIStackView

I have a fairly simple code which, upon clicking a button, adds a randomly colored UIView to a UIStackView , and upon a different button click, removes a random UIView from the UIStackView .我有一个相当简单的代码,单击按钮后,将随机着色的UIView添加到UIStackView ,并在单击不同的按钮时从UIStackView删除随机UIView

Here's the code:这是代码:

import UIKit

class ViewController: UIViewController, Storyboarded {
    weak var coordinator: MainCoordinator?
    @IBOutlet weak var stackView: UIStackView!
    
    var tags: [Int] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func buttonPressed(_ sender: UIButton) {
        switch sender.tag {
            case 10:
                let view = UIView(frame: CGRect(x: 0, y: 0, width: stackView.frame.width, height: 20))
                var number = Int.random(in: 0...10000)
                
                while tags.contains(number) {
                    number = Int.random(in: 0...10000)
                }
                
                tags.append(number)
                view.tag = number
                view.backgroundColor = .random()
                stackView.addArrangedSubview(view)
            case 20:
                if tags.count == 0 {
                    print("Empty")
                    return
                }
                
                let index = Int.random(in: 0...tags.count - 1)
                let tag = tags[index]
                
                tags.remove(at: index)
                
                if let view = stackView.arrangedSubviews.first(where: { $0.tag == tag }) {
                    stackView.removeArrangedSubview(view)
                }
            default:
                break
        }
    }
}

extension CGFloat {
    static func random() -> CGFloat {
        return CGFloat(arc4random()) / CGFloat(UInt32.max)
    }
}

extension UIColor {
    static func random() -> UIColor {
        return UIColor(
           red:   .random(),
           green: .random(),
           blue:  .random(),
           alpha: 1.0
        )
    }
}

I'm not using removeFromSuperview on purpose - since I would (later) want to reuse those removed UIViews , and that is why I'm using removeArrangedSubview .我不是故意使用removeFromSuperview - 因为我(稍后)想要重用那些删除的UIViews ,这就是我使用removeArrangedSubview

The issue I'm facing is:我面临的问题是:

All UIViews are removed as expected (visually of course, I know they're still in the memory) until I reach the last one - which, even though was removed, still appears and filling the entire UIStackView .所有UIViews都按预期删除(当然,在视觉上,我知道它们仍在内存中)直到我到达最后一个 - 即使被删除,它仍然出现并填充整个UIStackView

What am I missing here?我在这里缺少什么?

You can understand removeArrangedSubview is for removing constraints that were assigned to the subview.您可以理解removeArrangedSubview用于删除分配给子视图的约束。 Subviews are still in memory and also still inside the parent view.子视图仍然在内存中,也仍然在父视图中。

To achieve your purpose, you can define an array as your view controller's property, to hold those subviews, then use removeFromSuperview .为了实现您的目的,您可以定义一个数组作为您的视图控制器的属性,以保存这些子视图,然后使用removeFromSuperview

Or use .isHidden property on any subview you need to keep it in memory rather than removing its contraints.或者在您需要将其保留在内存中而不是删除其.isHidden任何子视图上使用.isHidden属性。 You will see the stackview do magical things to all of its subviews.你会看到 stackview 对它的所有子视图做了神奇的事情。

let subview = UIView()
stackView.addArrangedSubview(subview)

func didTapButton(sender: UIButton) {
   subview.isHidden.toggle()
}

Last, addArrangedSubview will do two things: add the view to superview if it's not in superview's hierachy and add contraints for it.最后, addArrangedSubview将做两件事:如果视图不在父视图的addArrangedSubview则将视图添加到父视图并为其添加addArrangedSubview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM