如何在 Swift 中切换可见性 GONE 和 VISIBLE

How to switch visibility GONE and VISIBLE in Swift

我想在可见性 GONEVISIBLE 之间切换。 这在 Android 开发中很容易实现,但我不知道如何在 Swift

中使用相同的方法

我尝试使用此代码将标签设置为已消失:

// set the width constraint to 0
let widthConstraint = NSLayoutConstraint(item:  self.labelShortDescription, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 0)
self.labelShortDescription.addConstraint(widthConstraint)

// set the height constraint to 0
let heightConstraint = NSLayoutConstraint(item:  self.labelShortDescription, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 0)
self.labelShortDescription.addConstraint(heightConstraint)

隐形:

This view is invisible, but it still takes up space for layout purposes.

要在 iOS 中实现:

yourView.alpha = 0

消失:

This view is invisible, and it doesn't take any space for layout purposes.

要在 iOS 中实现:

yourView.removeFromSuperview()

为了更新您的视图的可见性,您可以使用名为"isVisible"

的属性
myCustomView?.isVisible 

如果您需要查看该视图是否仍然是视图层次结构的一部分,您可以使用应包含该视图的超级视图中的子视图属性进行检查

myController.view.subviews.contains(myCustomView)

需要考虑的其他方面

myCustomView?.alpha = 0 //(visible but transparent)
myCustomView == nil //(not initialized)

通过更改 isHidden 和更改约束值来更改可见性

有效:

func visibilityLogo(visibility : Bool){

        self.img.isHidden = !visibility
        self.viewImageConstrain.constant = visibility ? 50 : 0
        self.viewConttrainParent.constant = visibility ? 50 : 0
        self.img.layoutIfNeeded()
    }
extension UIView {

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

我在 swift 中编写了一个 UIView 扩展来管理视图可见性,类似于 android SDK 视图可见性方法。

此扩展程序自动添加所需的约束以垂直、水平或同时折叠视图。这些约束永远不会被多次添加,只有当可见性类型为 gonegoneYgoneX[= 时才需要它们28=]。当可见性再次动态更改为可见或不可见状态时,它们会自动设置为 未激活visibleinvisible 状态由 isHidden 属性 管理,因此视图不可见但它仍然需要 space.

扩展

extension UIView {

    // MARK: visibility methods

    public enum Visibility : Int {
        case visible = 0
        case invisible = 1
        case gone = 2
        case goneY = 3
        case goneX = 4
    }

    public var visibility: Visibility {
        set {
            switch newValue {
                case .visible:
                    isHidden = false
                    getConstraintY(false)?.isActive = false
                    getConstraintX(false)?.isActive = false
                case .invisible:
                    isHidden = true
                    getConstraintY(false)?.isActive = false
                    getConstraintX(false)?.isActive = false
                case .gone:
                    isHidden = true
                    getConstraintY(true)?.isActive = true
                    getConstraintX(true)?.isActive = true
                case .goneY:
                    isHidden = true
                    getConstraintY(true)?.isActive = true
                    getConstraintX(false)?.isActive = false
                case .goneX:
                    isHidden = true
                    getConstraintY(false)?.isActive = false
                    getConstraintX(true)?.isActive = true
            }
        }
        get {
            if isHidden == false {
                return .visible
            }
            if getConstraintY(false)?.isActive == true && getConstraintX(false)?.isActive == true {
                return .gone
            }
            if getConstraintY(false)?.isActive == true {
                return .goneY
            }
            if getConstraintX(false)?.isActive == true {
                return .goneX
            }
            return .invisible
        }
    }

    fileprivate func getConstraintY(_ createIfNotExists: Bool = false) -> NSLayoutConstraint? {
        return getConstraint(.height, createIfNotExists)
    }

    fileprivate func getConstraintX(_ createIfNotExists: Bool = false) -> NSLayoutConstraint? {
        return getConstraint(.width, createIfNotExists)
    }

    fileprivate func getConstraint(_ attribute: NSLayoutConstraint.Attribute, _ createIfNotExists: Bool = false) -> NSLayoutConstraint? {
        let identifier = "random_id"
        var result: NSLayoutConstraint? = nil
        for constraint in constraints {
            if constraint.identifier == identifier {
                result = constraint
                break
            }
        }
        if result == nil && createIfNotExists {
            // create and add the constraint
            result = NSLayoutConstraint(item: self, attribute: attribute, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0)
            result?.identifier = identifier
            addConstraint(result!)
        }
        return result
    }
}

用法

myView.visibility = .visible
myView.visibility = .invisible
myView.visibility = .gone
myView.visibility = .goneX
myView.visibility = .goneY

这是对 Farshid roohi 回答的阐述:

您要做的是在 Storyboard 中创建一个约束来定义字段的高度。如果你不使用固定高度,它会更复杂,但你应该从这个答案中得到这个想法。 所以你为你的领域创建了一个高度限制。 然后,您在代码中为您的约束创建一个 IBOutlet,如下所示:

@IBOutlet weak var myItemsHeight: NSLayoutConstraint!

在 Storyboard 中,您 select 您的约束,然后将其引用出口连接到您刚刚在上面定义的变量。这就像为视图创建一个引用出口,但是您在左侧 Storyboard 导航器中的 selection 应该在实际约束上,而不是您正在约束的视图上。

现在在您的代码中,当您希望项目消失时,您可以设置:

myItemsHeight.constant = 0

当你想让它可见时,你可以将它的高度设置为任何应该的高度。

如果你想更漂亮,将所有布局信息都留在 Storyboard 中,你可以创建两个高度约束,一个值为 0,另一个值为你想要​​的高度。然后在您的代码中,当您希望该项目消失时,您可以执行以下操作:

myItemGoneConstraint.priority = 1000
myItemVisibleConstraint.priority = 0

并在您希望它可见时执行相反的操作