以编程方式清空 UIStackView
Programmatically emptying UIStackView
我有一个相当简单的代码,在单击一个按钮时,将随机颜色的 UIView
添加到 UIStackView
,并在单击不同的按钮时删除随机的 UIView
来自 UIStackView
.
代码如下:
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: { [=10=].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
)
}
}
我不是故意使用 removeFromSuperview
- 因为我(稍后)想重新使用那些删除的 UIViews
,这就是我使用 removeArrangedSubview
的原因。
我面临的问题是:
所有 UIViews
都按预期删除(当然,在视觉上,我知道它们仍在内存中)直到我到达最后一个 - 尽管已被删除,但仍然出现并填满整个UIStackView
.
我在这里错过了什么?
您可以理解 removeArrangedSubview
是为了删除分配给子视图的约束。子视图仍在内存中,也仍在父视图中。
为了达到你的目的,你可以定义一个数组作为你的视图控制器的 属性,来保存那些子视图,然后使用 removeFromSuperview
.
或者在任何子视图上使用 .isHidden
属性,您需要将其保存在内存中而不是移除其约束。您会看到 stackview 对其所有子视图做了神奇的事情。
let subview = UIView()
stackView.addArrangedSubview(subview)
func didTapButton(sender: UIButton) {
subview.isHidden.toggle()
}
最后,addArrangedSubview
会做两件事:如果视图不在 superview 的层次结构中,则将它添加到 superview 并为其添加约束。
我有一个相当简单的代码,在单击一个按钮时,将随机颜色的 UIView
添加到 UIStackView
,并在单击不同的按钮时删除随机的 UIView
来自 UIStackView
.
代码如下:
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: { [=10=].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
)
}
}
我不是故意使用 removeFromSuperview
- 因为我(稍后)想重新使用那些删除的 UIViews
,这就是我使用 removeArrangedSubview
的原因。
我面临的问题是:
所有 UIViews
都按预期删除(当然,在视觉上,我知道它们仍在内存中)直到我到达最后一个 - 尽管已被删除,但仍然出现并填满整个UIStackView
.
我在这里错过了什么?
您可以理解 removeArrangedSubview
是为了删除分配给子视图的约束。子视图仍在内存中,也仍在父视图中。
为了达到你的目的,你可以定义一个数组作为你的视图控制器的 属性,来保存那些子视图,然后使用 removeFromSuperview
.
或者在任何子视图上使用 .isHidden
属性,您需要将其保存在内存中而不是移除其约束。您会看到 stackview 对其所有子视图做了神奇的事情。
let subview = UIView()
stackView.addArrangedSubview(subview)
func didTapButton(sender: UIButton) {
subview.isHidden.toggle()
}
最后,addArrangedSubview
会做两件事:如果视图不在 superview 的层次结构中,则将它添加到 superview 并为其添加约束。