【问题标题】:iOS view visibility goneiOS 视图可见性消失了
【发布时间】:2018-07-15 07:55:30
【问题描述】:

我是 iOS 开发新手。我想从父视图切换(隐藏/可见)子视图。在 android 中有一种方法可以隐藏可见性消失。

在安卓中

subView.setVisibility(View.GONE);

在 iOS 中

subView.removeFromSuperview()

当我使用上述函数时,它会删除 subViewConstraints 并弄乱我的滚动视图约束。

topsubView.bottomAnchor.constraint(equalTo: bottomSubView.topAnchor, constant: 8).isActive = true

当我使用上面的代码时,它可以正常工作并隐藏 subView。但是当我想让 subView 可见时,它没有显示 subView。

topsubView.bottomAnchor.constraint(equalTo: bottomSubView.topAnchor, constant: 8).isActive = false
self.view.layoutIfNeeded()

希望你能理解我的问题。在此先感谢。

【问题讨论】:

  • 使用subView.isHidden = true
  • 谢谢。但我也想删除 subView 的空间。 subView.isHidden 没有删除空间
  • 查看我的解决方案
  • 那么你应该使用 UIStackView 并添加子视图。当它的子视图被隐藏时它也会隐藏空间
  • 设置你的视图高度限制,当你想删除空间时设置为0。

标签: ios swift swift3 view swift4


【解决方案1】:

由于我在 iOS 和 Android 上都工作过,您需要在 ios 中使用约束插座来实现 Android 功能。 iOS 不支持自动像 Android 原生支持可见性 GONE & VISIBLE

您需要将特定constraintoutlet 挂钩(可能是垂直/水平/高度),您需要将其设置为0 并需要管理您的用户界面。

隐藏:

self.viewYourConstraint.constant = 0
self.yourView.hidden = true
self.view.layoutIfNeeded()

展示:

self.viewYourConstraint.constant = 100//your constant value
self.yourView.hidden = false
self.view.layoutIfNeeded()

注意:如果上述约束的更新会影响到其他约束,还必须调用以下语句:

self.yourView.setNeedsUpdateConstraints()

干杯

【讨论】:

  • @John Fine,请接受它,这将帮助其他人找到确切的解决方案。
  • 将高度约束设置为0时是否需要隐藏部分?
  • 这就是它在 iOS 中的工作方式,在 IOS 上没有消失功能。不知何故,即使您从超级视图中删除视图,您也必须再次创建该视图..
  • 好吧,我有类似的代码,但不使用self.yourView.hidden = true,一切正常,因为当我想要隐藏视图时,我将视图的高度约束设为 0。
  • 是的,没错,但 iOS 中的最佳做法是我们也应该隐藏视图。
【解决方案2】:

试试这个扩展:

extension UIView {

    func visiblity(gone: Bool, dimension: CGFloat = 0.0, attribute: NSLayoutAttribute = .height) -> Void {
        if let constraint = (self.constraints.filter{$0.firstAttribute == attribute}.first) {
            constraint.constant = gone ? 0.0 : dimension
            self.layoutIfNeeded()
            self.isHidden = gone
        }
    }
}

// 你怎么用这个....

@IBOutlet weak var testView: UIView?
@IBAction func testVisibilty(switchbutton: UISwitch) -> Void {

    let viewHeight:CGFloat = switchbutton.isOn ? 100 : 0.0
    self.testView?.visiblity(gone: !switchbutton.isOn, dimension: viewHeight)

    // set visibility for width constraint
    //let viewWidth:CGFloat = switchbutton.isOn ? 300 : 0.0
    //self.testView?.visiblity(gone: !switchbutton.isOn, dimension: viewWidth, attribute: .width)

}

结果如下:

【讨论】:

  • 为什么这个扩展会重置属性
【解决方案3】:

也许你更喜欢这个解决方案

extension UIView {

    enum Visibility {
        case visible
        case invisible
        case gone
    }

    var visibility: Visibility {
        get {
            let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)
            if let constraint = constraint, constraint.isActive {
                return .gone
            } else {
                return self.isHidden ? .invisible : .visible
            }
        }
        set {
            if self.visibility != newValue {
                self.setVisibility(newValue)
            }
        }
    }

    private func setVisibility(_ visibility: Visibility) {
        let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)

        switch visibility {
        case .visible:
            constraint?.isActive = false
            self.isHidden = false
            break
        case .invisible:
            constraint?.isActive = false
            self.isHidden = true
            break
        case .gone:
            if let constraint = constraint {
                constraint.isActive = true
            } else {
                let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
                self.addConstraint(constraint)
                constraint.isActive = true
            }
        }
    }
}

那么用法是:

someView.visibility = .visible
someView.visibility = .invisible
someView.visibility = .gone

编辑:

改进功能:将在“可见性状态”中从情节提要(只需写:'visible'、'invisible'、'gone')工作

视图内的所有约束都应小于 1000

extension UIView {

    enum Visibility: String {
        case visible = "visible"
        case invisible = "invisible"
        case gone = "gone"
    }

    var visibility: Visibility {
        get {
            let constraint = (self.constraints.filter{$0.firstAttribute == .height && $0.constant == 0}.first)
            if let constraint = constraint, constraint.isActive {
                return .gone
            } else {
                return self.isHidden ? .invisible : .visible
            }
        }
        set {
            if self.visibility != newValue {
                self.setVisibility(newValue)
            }
        }
    }

    @IBInspectable
    var visibilityState: String {
        get {
            return self.visibility.rawValue
        }
        set {
            let _visibility = Visibility(rawValue: newValue)!
            self.visibility = _visibility
        }
    }

    private func setVisibility(_ visibility: Visibility) {
        let constraints = self.constraints.filter({$0.firstAttribute == .height && $0.constant == 0 && $0.secondItem == nil && ($0.firstItem as? UIView) == self})
        let constraint = (constraints.first)

        switch visibility {
        case .visible:
            constraint?.isActive = false
            self.isHidden = false
            break
        case .invisible:
            constraint?.isActive = false
            self.isHidden = true
            break
        case .gone:
            self.isHidden = true
            if let constraint = constraint {
                constraint.isActive = true
            } else {
                let constraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 0)
                // constraint.priority = UILayoutPriority(rawValue: 999)
                self.addConstraint(constraint)
                constraint.isActive = true
            }
            self.setNeedsLayout()
            self.setNeedsUpdateConstraints()
        }
    }
}

【讨论】:

    【解决方案4】:

    你说你想隐藏你的子视图并删除它占据的空间。如果您想避免混淆约束,可以尝试使用堆栈视图:

    • 创建UIStackView 并在堆栈视图与其父视图之间设置适当的约束;
    • 向堆栈视图添加视图;
    • 现在您可以通过将 view.isHidden 设置为 true 或 false 来切换堆栈视图中这些视图的可见性,并且布局将自动调整。

    【讨论】:

    • 如果视图没有固定间距怎么办?
    • 这是最快和最简单的解决方案,但可能不是所有情况下的最佳解决方案! @sandpat 您只需要在没有固定大小的堆栈内设置视图,以及该视图内视图的顶部和底部(或前导和尾随)的两个约束。
    【解决方案5】:

    我相信您正在寻找view.isHidden = true。这只是将视图隐藏在适当的位置,而不会更改视图层次结构或约束映射。您可以随后重新显示您的视图。 view.isHidden = false

    【讨论】:

    • 谢谢,但我也想删除 subView 的空间
    猜你喜欢
    • 1970-01-01
    • 2013-11-09
    • 2015-04-17
    • 1970-01-01
    • 2017-10-24
    • 2014-10-05
    • 1970-01-01
    • 2015-12-12
    • 2020-12-05
    相关资源
    最近更新 更多