web-dev-qa-db-ja.com

iOSでAndroidのように可視性がなくなったように設定する方法は?

ラベルを非表示にして、画面の他のビューに空白のままにした場所を使用させる簡単な方法を知っている人はいますか?そして、そのビューを表示するときは反対になります。 Android setVisibility = GONE forlayersのようなもの。

私の知る限り、setHidden = trueを使用すると、画面からビューが非表示になるだけで、周囲に何も再配置されません。

ありがとうございました

13
Siddharth Shah

IOSでAndroids.GONE機能を実現する唯一の方法は、UIStackViewを使用することです。

経由 アップルのドキュメント

スタックビューのコンテンツの動的な変更スタックビューは、ビューがarrangedSubviews配列に追加、削除、または挿入されるたび、または配置されたサブビューの非表示プロパティの1つが変更されるたびに、レイアウトを自動的に更新します。

スウィフト3:

// Appears to remove the first arranged view from the stack.
// The view is still inside the stack, it's just no longer visible, and no longer contributes to the layout.
let firstView = stackView.arrangedSubviews[0]
firstView.hidden = true

スウィフト4:

let firstView = stackView.arrangedSubviews[0]
firstView.isHidden = true
12
Fonix

これは、AutoLayout制約を使用して簡単に実現できます。

次のような3つのビューがあるとします。

+-----+
|  A  |
+-----+
+-----+
|  B  |
+-----+
+-----+
|  C  |
+-----+

場合によっては、ビューBを非表示にします。

次のように制約を設定します(これらは単なる値の例です)。

B top space to A:  4
C top space to B:  4
B height: 20

次に、Bの高さのNSLayoutConstraintアウトレットをコードに作成します。これを行うには、IBで制約をドラッグアンドドロップします。

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bHeight;

最後に、ビューを非表示にするには、次の手順を実行します。

self.bHeight = 0;

テーブルビューセルに対してこれを実行している場合、一部のセルにはBを表示し、他のセルには表示しない場合があることに注意してください。

この場合、高さを表示したいセルの「通常」の値に高さをリセットする必要があります。

self.bHeight = 24;
2
northernman

私は簡単な解決策を探していて、それを見つけました。 UIStackViewを使用したり、制約用のアウトレットを作成したりする必要はありません。これを使用するだけです:

class GoneConstraint {
    private var constraint: NSLayoutConstraint
    private let prevConstant: CGFloat

    init(constraint: NSLayoutConstraint) {
        self.constraint = constraint
        self.prevConstant = constraint.constant
    }

    func revert() {
        self.constraint.constant = self.prevConstant
    }
}


fileprivate struct AssociatedKeys {
    static var widthGoneConstraint: UInt8 = 0
    static var heightGoneConstraint: UInt8 = 0
}


@IBDesignable
extension UIView {

    @IBInspectable
    var gone: Bool {
        get {
            return !self.isHidden
        }
        set {
            update(gone: newValue)
        }
    }

    weak var widthConstraint: GoneConstraint? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.heightGoneConstraint) as? GoneConstraint
        }
        set(newValue) {
            objc_setAssociatedObject(self, &AssociatedKeys.widthGoneConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    weak var heightConstraint: GoneConstraint? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.heightGoneConstraint) as? GoneConstraint
        }
        set(newValue) {
            objc_setAssociatedObject(self, &AssociatedKeys.heightGoneConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    private func update(gone: Bool) {
        isHidden = gone
        if gone {
            for constr in self.constraints {
                if constr.firstAttribute == NSLayoutAttribute.width {
                    self.widthConstraint = GoneConstraint(constraint: constr)
                }
                if constr.firstAttribute == NSLayoutAttribute.height {
                    self.heightConstraint = GoneConstraint(constraint: constr)
                }
                constr.constant = 0
            }
        } else {
            widthConstraint?.revert()
            heightConstraint?.revert()
        }
    }
}

これで、view.gone = trueを呼び出すことができます。これで完了です。

2
Daniel Kuta

アプリがiOS9以降をサポートしている場合は、UIStackViewを使用できます。

ただし、アプリがios 8もサポートしている場合は、自動レイアウトを使用してそれを実現し、ビューの高さ制約を追加する必要があります

したがって、非表示にする場合は、高さ制約値を0に設定するだけではありません。

1
Shreyank