简体   繁体   English

快速删除 UIstackview 中的视图

[英]Remove views in UIstackview swift

I am new to swift.我是 swift 的新手。 I have added view to stackview using addArrangedSubview() .我已经使用addArrangedSubview()向 stackview 添加了视图。 But I am not able to remove this view using removeArrangedSubview() .但我无法使用removeArrangedSubview()删除此视图。 Even after removing arranged subView the view is still present即使删除排列的子视图后,视图仍然存在

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)

}

In another function I am removing the arranged subview在另一个函数中,我正在删除排列好的子视图

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)
}

and my mainview is created as:我的主视图创建为:

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)
}

I want the username & button to be deleted and add new field firstname to the subview.我希望删除usernamebutton并将新字段firstname添加到子视图。

Am I doing it the right way ?我这样做对吗? How to delete subview ?如何删除子视图? Thanks for any help谢谢你的帮助

In Swift 5.4在 Swift 5.4 中

removeArrangedSubview method removes the provided view from the stack's arrangedSubviews array. removeArrangedSubview 方法从堆栈的排列子视图数组中删除提供的视图。 The view's position and size will no longer be managed by the stack view.视图的位置和大小将不再由堆栈视图管理。 However, this method does not remove the provided view from the stack's subviews array;但是,此方法不会从堆栈的 subviews 数组中删除提供的视图; therefore, the view is still displayed as part of the view hierarchy.因此,视图仍然显示为视图层次结构的一部分。

To prevent the view from appearing on screen after calling the stack's removeArrangedSubview: method, explicitly remove the view from the subviews array by calling the view's removeFromSuperview() method, or set the view's isHidden property to true.要防止在调用堆栈的 removeArrangedSubview: 方法后视图出现在屏幕上,请通过调用视图的 removeFromSuperview() 方法从子视图数组中显式删除视图,或将视图的 isHidden 属性设置为 true。

So:所以:

myStackView.removeArrangedSubview(myView)
myView.removeFromSuperview()

Extended If you have a series of arranged subview, and you want to clean them, You can also create an extension: Extended如果你有一系列排列好的子视图,并且想要清理它们,你也可以创建一个扩展:

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

If you want to hide a view within a stack view, all you have to do is set the contained view's hidden property to true and the stack view handles the rest.如果你想在一个堆栈视图中隐藏一个视图,你所要做的就是将包含的视图的 hidden 属性设置为 true ,堆栈视图处理其余的。

So what you must call as far as I understood from your code is the following:因此,据我从您的代码中了解到,您必须调用的内容如下:

subview.hidden = true

By my experience backed by actually testing the implementation (😉), all you have to do to remove subview from stackView is call removeFromSuperview() method on every subview of the stackView:根据我实际测试实现(😉)的经验,从 stackView 中删除子视图所需要做的就是在 stackView 的每个子视图上调用 removeFromSuperview() 方法:

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

This is how it looks in console:这是它在控制台中的样子:

(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>>

Then you remove all subviews:然后删除所有子视图:

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

And the result:结果:

(lldb) po stackView.subviews
0 elements

(lldb) po stackView.arrangedSubviews
0 elements

You can make extension to UIStackView to save you some typing in the future:您可以扩展 UIStackView 以节省您将来的一些输入:

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

You are on the right track, but there are a few issues with your code.您走在正确的轨道上,但您的代码存在一些问题。

First, you should only call self.view.addSubview(mainview) once, in mainviewlet .首先,您应该只在mainviewlet调用self.view.addSubview(mainview)一次。 You should not be doing this again in login and signup .您不应在loginsignup再次执行此操作。

EDIT: removed second comment because it was incorrect.编辑:删除第二条评论,因为它不正确。

Third, your calls to addArrangedSubview and removeArrangedSubview should be balanced.第三,您对addArrangedSubviewremoveArrangedSubview调用应该是平衡的。 You are adding username and button to your subview but never removing them.您正在向subview添加usernamebutton ,但从未删除它们。 You need to remove them if you want them to disappear.如果您希望它们消失,则需要删除它们。

If you want to remove the view without referencing it again:如果要删除视图而不再次引用它:

  1. Make sure the view is connected via outlets确保视图通过插座连接
  2. fooView.removeFromSuperview()

The stackView will be drawn with fooView removed将在移除 fooView 的情况下绘制fooView

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

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