79

我正在为 iOS 开发一个应用程序,并且我正在使用带有 AutoLayout ON 的 Storyboard。我的一个视图控制器有一组 4 个按钮,在某些情况下我想让第一个按钮消失。

如果我使用该setHidden:TRUE方法,UIButton 会变得不可见,但它仍然明显占用视图中的空间,结果是一个“洞”,我无法填充它,使剩余的 UIButton 浮向主视图的顶部。

在 Android 中,我会简单地使用View.GONE而不是View.INVISIBLE,但在 iOS 中,我一直坚持这种行为,我不想相信唯一的解决方案是手动(是的,我的意思是以编程方式)将剩余元素移动到顶部。

我以为我可以通过设置某种约束来使一切都像在 Android 中一样自动化,但我没有运气。

在我关闭自动布局之前,有人可以指出正确的方向吗?

我正在使用 IB,但我也对程序化的东西感到满意。

更新:

将组件高度设置为 0 也无济于事。

我试过这样的事情:

UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;
4

13 回答 13

40

添加一个将视图高度设置为 0 的约束(NSLayoutAttributeHeight)对我有用:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];
于 2014-03-26T19:06:03.023 回答
20

关于这个问题的所有答案都是低效的。在 iOS 上等效于 Android setVisibility:Gone 方法的最佳方法是StackView首先选择组件,然后在编辑器中,嵌入,堆栈视图,

用 IBOutlet 连接新的堆栈视图,然后:

隐:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = YES;

能见度:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = NO;

与使用堆栈视图一样,所有约束都将被保留!

文档

于 2016-09-25T12:47:04.567 回答
16

向视图添加高度约束,如下所示:在此处输入图像描述

然后在 viewController 文件中为高度约束创建一个出口,如下所示:在此处输入图像描述

& 然后在您的 viewDidLoad 方法中将约束高度更改为 0,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()
nsLcButtonHeight.constant = 0
}
于 2016-01-20T16:54:06.790 回答
8

要在 iOS 上实现 Androids.GONE 功能,需要使用 UIStackView。之后按位置隐藏孩子。(苹果文档

斯威夫特 4:

let firstView = cell.rootStackView.arrangedSubviews[0]
    firstView.isHidden = true // first view gone

这是一个表格单元格示例,只需将两个内部都放入并为孩子Stack view获取项目。GONE

在此处输入图像描述

于 2018-02-18T06:43:22.173 回答
6

您可以做的是将您的视图分组到堆栈视图下。然后,当您隐藏特定视图时,其余视图将自动移动以填充空间。

您可能需要查看有关堆栈视图的 Apple 文档: https ://developer.apple.com/reference/uikit/uistackview

或在线教程,例如:https ://www.appcoda.com/stack-views-intro/

于 2017-02-05T05:03:26.660 回答
1

https://github.com/tazihosniomar/LayoutManager

我希望它会帮助你。

于 2014-05-13T15:33:10.350 回答
1

1) 如果您的按钮是垂直放置的,那么您必须将 设置height为 0,如果是水平放置的按钮,请尝试设置width为 0,或者您可以将两者都设置为 0。

或者

2)你可以尝试这种方法,它设置button2button1

- (void)viewDidLoad
{
[super viewDidLoad];

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:@"hello" forState:UIControlStateNormal];

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setTitle:@"world" forState:UIControlStateNormal];

[button1 sizeToFit]; [button2 sizeToFit];
[button2 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];

[self.view addSubview:button1];
[self.view addSubview:button2];

}
于 2013-07-26T09:14:43.797 回答
1

这个问题已经很老了,但我发现的最重要的事情是设置额外的约束(所以“消失”视图周围的视图知道一旦丢失该怎么办)

A  which you want to be     A
|  after setting B to gone  |
B                           C
|                               
C                               
  1. 设置从 C 到 A 的较低优先级 (750) 约束。
  2. 将 B 的顶部和底部约束(如果您希望视图水平折叠,则添加左右)到 NSLayoutConstraint 数组bConstraints。通过以下方式执行此操作:
    1. 控制单击并从约束拖动到 ViewController
    2. 将连接从 Outlet 更改为 Outlet Collection
    3. 对于名称 put bConstraints
    4. 点击连接。@IBOutlet var bConstraints: [NSLayoutConstraint]!这将在您的 ViewController 中创建一个
    5. 要添加其他约束:从 Storyboard 中的约束拖动到 @IBOutlet 变量名
  3. 然后隐藏B

    B.hidden = true
    NSLayoutConstraint.deactivateConstraints(bConstraints)
    
  4. 取消隐藏

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    

显然,您拥有的视图越多,这就越复杂,因为您需要每个视图的附加约束

于 2017-01-06T21:59:52.273 回答
0

根据 Deniz 提供的答案,这是一个在 Swift 中使用约束的解决方案

例如:如果您有 3 个视图,A_view B_view 和 C_view 以该顺序垂直对齐,并且您想要“隐藏”B 并调整差异,添加一个约束

B_view.removeFromSuperView()
var constr = NSLayoutConstraint(item: C_view, 
                                attribute: NSLayoutAttribute.Top, 
                                relatedBy: NSLayoutRelation.Equal, 
                                toItem: A_view, 
                                attribute: NSLayoutAttribute.Bottom,
                                multiplier: 1,
                                constant: 20)
view.addConstraint(constr)

常量是(在这种情况下)C_view 和 A_view 之间的垂直空间量

于 2015-02-25T04:30:18.000 回答
0

正如我的研究表明的那样,即使是 AutoLayout 也无法为您提供帮助。您必须手动替换受可选显示组件影响的视图(在我的情况下,所有视图都位于可选视图的底部,但我相信您可以调整它以处理可选按钮右侧的所有按钮):

- (IBAction)toggleOptionalView:(id)sender {
    if (!_expanded) {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, _optionalHeight);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = YES;
    } else {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, 0);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = NO;

    }
}

建议不要对可选组件的高度/宽度进行硬编码,否则每次编辑 XIB/Storyboard 时代码都会中断。我在 viewDidLoad 中设置了一个字段 float _optionalHeight,因此它始终是最新的。

于 2014-03-14T10:05:44.973 回答
0

我向自定义 UIView 实现添加了一个名为“visible”的新属性,当它设置为 false 时,会添加一个约束以折叠视图(我只添加了一个宽度约束,因为我的列表是水平的,但最好的方法可能是添加一个0 的高度约束)。

var visible:Bool = true{
        didSet{
            if(visible){
                clipsToBounds = false;
                removeConstraint(hideConstraint!)
            }else{
                clipsToBounds = true
                addConstraint(hideConstraint!)
            }
        }
    }

您需要在视图上初始化零宽度约束并将其添加为字段:

private var hideConstraint:NSLayoutConstraint?


func someInitFunction(){
    hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
    ...
}
于 2015-02-25T13:32:58.610 回答
0

您还可以清除页面,或者至少清除页面的某些单元格,然后重新定义整个内容。它速度快而且效果很好。我没有编写代码,但在我正在处理的这个预先存在的项目中找到了它。创建ManagementTableSectionManagementTableCell类来管理这一切。抱歉,我无法提供更好定义的代码。

于 2014-09-17T14:38:39.063 回答
-3

setHidden:TRUE/FALSE 是最接近 Android View.GONE/VISIBLE 的等效项。

如果不可见,视图不一定占用空间!

我制作了一个类似于 ComboBox 的 ListView,它位于其他视图之上。我只在选择时可见:

在此处输入图像描述

于 2014-10-11T10:32:02.127 回答