iOS视图可见性消失了

问题描述 投票:15回答:5

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

在android中

subView.setVisibility(View.GONE);

在iOS中

subView.removeFromSuperview()

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

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

当我使用上面的代码它工作正常并隐藏subView.but当我想使subView可见时,它不显示subView。

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

希望你能理解我的问题。谢谢你提前。

ios swift swift3 view swift4
5个回答
22
投票

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

你需要挂钩特定outletconstraint(它可能垂直/水平/高度)你需要将它设置为0并需要管理你的UI。

隐藏:

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

干杯


10
投票

试试这个扩展:

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)

}

结果如下:

enter image description here


5
投票

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

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

编辑:

提高能力:将在“可见性状态”中从故事板(只写:'可见','隐形','消失')开始工作

视图内的所有约束应小于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()
        }
    }
}

3
投票

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

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

2
投票

我相信你正在寻找view.isHidden = true。这只是简单地隐藏视图而不改变视图层次结构或约束映射。您随后可以重新显示您的视图。与view.isHidden = false

© www.soinside.com 2019 - 2024. All rights reserved.