删除 UIstackview 中的视图 swift

Remove views in UIstackview swift

我是 swift 的新手。我已使用 addArrangedSubview() 将视图添加到堆栈视图。但是我无法使用 removeArrangedSubview() 删除此视图。 即使在删除排列的子视图之后,视图仍然存在

import Foundation
import UIKit

class render: UIViewController {

  let subview    = UIStackView()
  let mainview   = UIStackView()

  override func viewDidLoad() {
    super.viewDidLoad()

    self.mainviewlet()
    self.login()
  }

  func login() {

    let username = UITextField()
    // text field

    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 40))
    //button

    // Adding to subview  
    subview.axis  = UILayoutConstraintAxis.vertical
    subview.distribution  = UIStackViewDistribution.equalSpacing
    subview.alignment = UIStackViewAlignment.center
    subview.spacing   = 16.0

    subview.addArrangedSubview(username)
    subview.addArrangedSubview(button)

    subview.translatesAutoresizingMaskIntoConstraints = false;

    // Adding subview to another stackview
    mainview.addArrangedSubview(subview)
    self.view.addSubview(mainview)

}

在另一个函数中,我正在删除排列的子视图

func signup(sender: UIButton!) {

    // Remove subview
    mainview.removeArrangedSubview(subview)
    subview.removeFromSuperview()

    let firstname = UITextField()
    firstname.textAlignment = NSTextAlignment.center
    firstname.textColor = UIColor.black
    firstname.frame = CGRect()
    firstname.frame.size.height = 30;
    firstname.text = "firstname"

    subview.addArrangedSubview(firstname)
    mainview.addArrangedSubview(subview)
    self.view.addSubview(mainview)
}

我的主视图创建为:

func mainviewlet {

  mainview.axis  = UILayoutConstraintAxis.vertical
  mainview.distribution  = UIStackViewDistribution.equalSpacing
  mainview.alignment = UIStackViewAlignment.center
  mainview.spacing   = 16.0
  mainview.translatesAutoresizingMaskIntoConstraints = false;

  self.view.addSubview(mainview)
}

我想删除 usernamebutton 并将新字段 firstname 添加到子视图。

我的做法正确吗?如何删除子视图?感谢您的帮助

如果你想在堆栈视图中隐藏一个视图,你所要做的就是将包含的视图的隐藏 属性 设置为 true,其余的由堆栈视图处理。

因此,据我从您的代码中了解到,您必须调用的内容如下:

subview.hidden = true

您的方向是正确的,但您的代码存在一些问题。

首先,您只应在 mainviewlet 中调用 self.view.addSubview(mainview) 一次。你不应该在 loginsignup.

中再次这样做

编辑:删除了第二条评论,因为它不正确。

第三,您对 addArrangedSubviewremoveArrangedSubview 的调用应该是平衡的。您将 usernamebutton 添加到您的 subview 但从未删除它们。如果你想让它们消失,你需要移除它们。

在Swift5.4

removeArrangedSubview 方法从堆栈的 arrangedSubviews 数组中删除提供的视图。视图的位置和大小将不再由堆栈视图管理。但是,此方法不会从堆栈的子视图数组中删除提供的视图;因此,该视图仍显示为视图层次结构的一部分。

要防止视图在调用堆栈的 removeArrangedSubview: 方法后出现在屏幕上,请通过调用视图的 removeFromSuperview() 方法从子视图数组中显式删除视图,或者将视图的 isHidden 属性 设置为 true .

所以:

myStackView.removeArrangedSubview(myView)
myView.removeFromSuperview()

扩展 如果你有一系列排列的子视图,你想清理它们,你也可以创建一个扩展:

extension UIStackView {
    
    func removeFully(view: UIView) {
        removeArrangedSubview(view)
        view.removeFromSuperview()
    }
    
    func removeFullyAllArrangedSubviews() {
        arrangedSubviews.forEach { (view) in
            removeFully(view: view)
        }
    }
    
}

根据我实际测试实现的经验 (),从 stackView 中删除子视图所需要做的就是在 stackView 的每个子视图上调用 removeFromSuperview() 方法:

stackView.subviews.forEach { (view) in
    view.removeFromSuperview()
}

这是它在控制台中的样子:

(lldb) po stackView.arrangedSubviews
▿ 3 elements
  - 0 : <UIStackView: 0x7f840c8297d0; frame = (0 0; 375 95); layer = <CATransformLayer: 0x600003f48c80>>
  - 1 : <UIStackView: 0x7f840c82f5e0; frame = (0 125; 375 95); layer = <CATransformLayer: 0x600003f54520>>
  ▿ 2 : <UIView: 0x7f840b3c93a0; frame = (0 250; 375 47); opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x600006bdae20>; layer = <CALayer: 0x600003f4a7e0>>

(lldb) po stackView.subviews
▿ 3 elements
  - 0 : <UIStackView: 0x7f840c8297d0; frame = (0 0; 375 95); layer = <CATransformLayer: 0x600003f48c80>>
  - 1 : <UIStackView: 0x7f840c82f5e0; frame = (0 125; 375 95); layer = <CATransformLayer: 0x600003f54520>>
  ▿ 2 : <UIView: 0x7f840b3c93a0; frame = (0 250; 375 47); opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x600006bdae20>; layer = <CALayer: 0x600003f4a7e0>>

然后删除所有子视图:

(lldb) expression stackView.subviews.forEach { (view) in view.removeFromSuperview() }

结果:

(lldb) po stackView.subviews
0 elements

(lldb) po stackView.arrangedSubviews
0 elements

您可以对 UIStackView 进行扩展以节省您以后的输入时间:

extension UIStackView {
    func removeAllSubviews() {
        subviews.forEach { (view) in
            view.removeFromSuperview()
        }
    }
}

如果您想删除视图而不再次引用它:

  1. 确保视图通过插座连接
  2. fooView.removeFromSuperview()

stackView 将在移除 fooView 的情况下绘制

你可以使用 while 循环。

let stack = UIStackView()
while let v = stack.arrangedSubviews.first {
    stack.removeArrangedSubview(v)
}