【问题标题】:Remove views in UIstackview swift快速删除 UIstackview 中的视图
【发布时间】:2017-05-19 21:56:17
【问题描述】:

我是 swift 新手。我使用addArrangedSubview() 将视图添加到stackview。但我无法使用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 添加到子视图中。

我做对了吗?如何删除子视图?感谢您的帮助

【问题讨论】:

  • 有什么问题?
  • @shallowThought ,即使我删除了子视图,按钮和文本框仍然存在
  • 您没有删除它们。缺少像subview.removeArrangedSubview(username) 这样的东西。
  • @shallowThought,你的意思是我需要一个一个删除它们?如果有更多这样的控件呢?

标签: ios user-interface uistackview


【解决方案1】:

在 Swift 5.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)
        }
    }
    
}

【讨论】:

  • 为什么不只是 myView.removeFromSuperview?这也行。
  • 也许吧,但我的问题是基于苹果开发者的。
  • 我很高兴它有帮助!
【解决方案2】:

如果您想在堆栈视图中隐藏视图,您只需将包含的视图的 hidden 属性设置为 true,然后堆栈视图处理其余部分。

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

subview.hidden = true

【讨论】:

  • 这是正确答案!您不需要从超级视图中删除视图。隐藏它是诀窍!谢谢
【解决方案3】:

根据我实际测试实现 (?) 的经验,从 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()
        }
    }
}

【讨论】:

    【解决方案4】:

    您在正确的轨道上,但您的代码存在一些问题。

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

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

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

    【讨论】:

    • 您可能需要查看docs for removeArrangedSubview:。 ”然而,这个方法不会从堆栈的子视图数组中删除提供的视图;因此,视图仍然显示为视图层次结构的一部分。”
    • @robmayoff 谢谢你,Rob,我已经纠正了。这是我的一个错误假设。
    【解决方案5】:

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

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

    stackView 将被删除,fooView 被移除

    【讨论】:

      【解决方案6】:

      你可以使用while循环来做到这一点。

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

      【讨论】:

        猜你喜欢
        • 2018-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多