web-dev-qa-db-ja.com

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をサブビューに追加します。

私はそれを正しい方法でやっていますか?サブビューを削除するには?助けてくれてありがとう

14
Ahalya

Swift 5.1

removeArrangedSubviewメソッドは、提供されたビューをスタックのexpandedSubviews配列から削除します。ビューの位置とサイズは、スタックビューによって管理されなくなります。ただし、このメソッドは提供されたビューをスタックのサブビュー配列から削除しません。したがって、ビューは引き続きビュー階層の一部として表示されます。

スタックのremoveArrangedSubview:メソッドを呼び出した後にビューが画面に表示されないようにするには、ビューのremoveFromSuperview()メソッドを呼び出してサブビュー配列からビューを明示的に削除するか、ビューのisHiddenプロパティをtrueに設定します。

そう:

myStackView.removeArrangedSubview(myView)
myView.removeFromSuperview()
17
Reimond Hill

スタックビュー内のビューを非表示にする場合は、含まれているビューのhiddenプロパティをtrueに設定するだけで、スタックビューが残りを処理します。

だから私があなたのコードから理解した限りあなたが呼ばなければならないのは以下です:

subview.hidden = true
25

実際の実装テスト(????)に裏打ちされた私の経験では、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()
        }
    }
}
2
Roman

あなたは正しい軌道に乗っていますが、コードにはいくつかの問題があります。

まず、mainviewletself.view.addSubview(mainview)を1回だけ呼び出す必要があります。 loginsignupでは、これを再度行うべきではありません。

編集:間違っていたため、2番目のコメントを削除しました。

3番目に、addArrangedSubviewremoveArrangedSubviewへの呼び出しはバランスが取れている必要があります。 usernamebuttonsubviewに追加しますが、削除しないでください。それらを消したい場合は削除する必要があります。

0
Mike Taverne