相当于 Android View.GONE 可见模式的 iOS

我正在为 iOS 开发一个应用程序,我使用的故事板与自动布局。我的一个视图控制器有一组4个按钮,在某些情况下,我想让第一个按钮消失。

如果我使用 setHidden:TRUE方法,UIButton 会变得不可见,但是它仍然在视图中占用空间,结果是一个“洞”,我还没有能够填充其余的 UIButton,使其浮动到主视图的顶部。

在 Android 系统中,我会简单地使用 View.GONE而不是 View.INVISIBLE,但是在 iOS 系统中,我被这种行为困住了,我不愿意相信唯一的解决方案是手动(是的,我的意思是程序化)移动剩余的元素到顶部。

我原以为我可以设置一些约束,让所有事情都像安卓系统一样自动化,但是我没有这个运气。

在我关闭自动设定之前,有人能给我指明正确的方向吗?

我使用的是 IB,但我对程序性的东西也很满意。

更新:

将组件高度设置为0也没有帮助。

我试过这样的方法:

UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;
33214 次浏览

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

或者

2)你可以尝试这种将 button2设置在 button1之上的方法:

- (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];


}

正如我的研究表明,即使自动布局也不能帮助你。你必须手动替换受可选显示组件影响的视图(在我的例子中,是可选视图底部的所有视图,但是你我确信你可以调整它来处理可选按钮右侧的所有按钮) :

- (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,因此它始终是最新的。

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

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];

您还可以清除该页面,或者至少清除该页面的某些单元格,并重新定义整个内容。速度快,效果好。我没有写代码,但发现它在这个预先存在的项目,我的工作。创建 ManagementTableSectionManagementTableCell类来管理它们。对不起,我不能提供更好的定义代码。

SetHidden: TRUE/FALSE 是最接近 Android View.GONE/VISIBLE 的等价物。

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

我已经创建了一个 ComboBox-Alike,其中的 ListView 位于其他视图之上:

enter image description here

基于 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 之间的垂直空间量

我在自定义的 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)
...
}

在视图中添加一个高度约束,如下所示:enter image description here

然后在 viewController 文件中创建一个高度约束的出口,如下所示:enter image description here

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

override func viewDidLoad() {
super.viewDidLoad()
nsLcButtonHeight.constant = 0
}

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

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

隐藏:

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

能见度:

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

当使用堆栈视图时,所有的约束都将被保留!

文件

这个问题已经很老了,但是我发现最隐蔽的是设置额外的约束(这样围绕“ gone”视图的视图知道一旦它丢失了该怎么做)

A  which you want to be     A
|  after setting B to gone  |
B                           C
|
C
  1. 设置从 C 到 A 的较低优先级(750)约束。
  2. 向 NSLayoutConstraint 数组 bConstraints中添加 B 的顶部和底部约束(如果希望视图水平折叠,则可以向左和向右)。这样做:
    1. 控件单击并从约束拖动到 ViewController
    2. 将连接从 Outlet 更改为 Outlet 集合
    3. 名字写 bConstraints
    4. 点击连接。这将在 ViewController 中创建一个 @IBOutlet var bConstraints: [NSLayoutConstraint]!
    5. 要添加其他约束: 从 Storyboard 中的约束拖动到@IBOutlet 变量名
  3. 那就把 B 藏起来

    B.hidden = true
    NSLayoutConstraint.deactivateConstraints(bConstraints)
    
  4. To unhide

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    

Obviously the more and more views you have the more complex this grows, as you need additional constraints from each view

您所能做的就是在堆栈视图下对视图进行分组。然后,当您隐藏某个特定视图时,其余视图将自动移位以填充空间。

你可能想看看关于堆栈视图的苹果文档: Https://developer.apple.com/reference/uikit/uistackview

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

要在 iOS 上实现 Androids.GONE 功能,需要使用 UIStackView,然后按位置隐藏子视图

SWIFT 4:

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

这是一个表格单元格的例子,只需要把两个都放在 Stack view中,然后为 GONE的子元素获取条目。

enter image description here