如何在Swift中隐藏元素及其所占空间

18

我想隐藏一个元素(在我的情况下是日期选择器),并且隐藏它的空间。因此,我尝试使用动画来实现:

@IBAction func showQnt(sender: AnyObject) {
    if (self.pickerQnt.alpha == 0.0) {
        UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions.ShowHideTransitionViews, animations: {
            self.pickerQnt.alpha = 1.0
            
            
            }, completion: {
                (finished: Bool) -> Void in
                //var constH = NSLayoutConstraint(item: self.pickerQnt, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 162)
                //self.pickerQnt.addConstraint(constH)
        })
    } else {
        UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions.ShowHideTransitionViews, animations: {
            self.pickerQnt.alpha = 0.0
            
            
            }, completion: {
            (finished: Bool) -> Void in
                // CHECK: ?!? constrain to set view height to 0 run time
                //var constH = NSLayoutConstraint(item: self.pickerQnt, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 0)
                //self.pickerQnt.addConstraint(constH)
        })
    }
}

我也尝试过类似的东西

self.pickerQnt.hidden = true
但是它不会起作用。 提前致谢。
4个回答

14

使用Objective-C/Swift中视图上的"hidden"属性实际上并没有“折叠”视图所占用的空间(与"Android中的View.GONE"相对)。

相反,您应该使用自动布局和高度约束。

在Xib/Storyboard文件中创建一个高度约束,并给它所需的高度。在约束列表中从约束中按住Ctrl拖动到您的源文件中,然后您可以编写此方法

Swift解决方案

var pickerHeightVisible: CGFloat!
...
...
func togglePickerViewVisibility(animated: Bool = true) {
    if pickerHeightConstraint.constant != 0 {
        pickerHeightVisible = pickerHeightConstraint.constant
        pickerHeightConstraint.constant = 0
    } else {
        pickerHeightConstraint.constant = pickerHeightVisible
    }
    if animated {
         UIView.animateWithDuration(0.2, animations: {
              () -> Void in
               self.view.layoutIfNeeded()
         }, completion: nil)
    } else {
         view.layoutIfNeeded()
    }
}

Objective-C解决方案:

@property (nonatomic, strong) CGFloat pickerHeightVisible;
...
...
- (void)togglePickerViewVisibility:(BOOL)animated {
    if(pickerHeightConstraint.constant != 0) {
        pickerHeightVisible = pickerHeightConstraint.constant;
        pickerHeightConstraint.constant = 0;
    } else {
        pickerHeightConstraint.constant = pickerHeightVisible;
    }
    if(animated) {
         [UIView animateWithDuration:0.2
             animations:(void (^)(void))animations:^(void) {
                  [self.view layoutIfNeeded];
             }];
    } else {
          [self.view layoutIfNeeded];
    }
}

免责声明:我没有测试或编译上面的代码,但它将为您提供实现它的想法。

重要提示:上述代码假定您在storyboard/nib中给选择器视图的高度约束赋值大于0。


2
5岁的答案,我知道但是从你的评论中学到了很多。我喜欢Swift,但我绝对讨厌UI方面。我从来没有理解过如何在iOS中使用“View.Gone”。我真的很感激你的回答。 - Zun
1
@Zun 非常感谢!我一直很讨厌 UIKit... 你尝试过 SwiftUI 吗?界面框架更好看!但在其他方面比较困难,导航有点棘手。 - Sajjon

11

这是一个旧问题,但对于新的iOS版本,有另一种可用选项:

如果您的布局允许,并且您的目标是,则可以将您的视图排列在UIStackView中作为容器。堆栈视图的子项在隐藏时会折叠,即不再占据任何空间。

动态更改堆栈视图的内容

当添加、删除或插入到arrangedSubviews数组中的视图或其中一个排列子视图的isHidden属性更改时,堆栈视图会自动更新其布局。

(https://developer.apple.com/documentation/uikit/uistackview#overview)


3

最好的方法是将视图添加到堆栈中,并在隐藏一个视图时自动调整堆栈视图的高度。但如果视图不在堆栈视图中,则只需执行以下操作。

1- 隐藏该视图。
2- 对视图分配高度约束,使高度约束成为该视图的出口。

@IBOutlet weak var myView: UIView!
@IBOutlet weak var myViewHeightConstraint: NSLayoutConstraint!
myView.isHidden = true
viewHeightConstraint.constant = 0

2
一个简单的方法是在隐藏视图时将高度设置为零(而不必使高度约束成为IBOutlet)。
myView.isHidden = true
myView.heightAnchor.constraint(equalToConstant: CGFloat(0)).isActive = true

再次显示时重新设置高度

myView.isHidden = false
myView.heightAnchor.constraint(equalToConstant: CGFloat(40)).isActive = true

要实现上述带有动画的功能,只需将heightAnchor代码放入UIView.animate()代码块中即可。

如果你需要经常这样做,那么可以通过创建扩展函数将两行代码简化为一行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接