iOS等效于Android View.GONE可见性模式

时间:2013-07-25 21:41:45

标签: iphone ios interface-builder visibility autolayout

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

如果我使用setHidden:TRUE方法,UIButton变得不可见但显然仍然在视图中占用空间,结果是一个"洞"我无法填补剩余的UIButton浮动到主视图的顶部。

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

我以为我能够设置某种约束来使一切都像Android一样自动但我没有运气。

在我关闭Autolayout之前,有人能指出我正确的方向吗?

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

更新

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

我试过这样的事情:

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

13 个答案:

答案 0 :(得分:37)

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

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

答案 1 :(得分:16)

为视图添加高度约束,如下所示:enter image description here

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

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

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

答案 2 :(得分:16)

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

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

隐藏的:

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

能见度:

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

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

Document

答案 3 :(得分:6)

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

您可能想查看堆栈视图上的Apple文档: https://developer.apple.com/reference/uikit/uistackview

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

答案 4 :(得分:5)

在iOS上实现Androids.GONE功能是使用UIStackView。之后,按位置隐藏孩子。 (Apples documentation

SWIFT 4:

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

这是一个表格单元格示例,只需将内部Stack viewGONE项目放在孩子身上。

enter image description here

答案 5 :(得分:1)

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

OR

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

}

答案 6 :(得分:1)

https://github.com/tazihosniomar/LayoutManager

我希望它会对你有所帮助。

答案 7 :(得分: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,所以它总是最新的。

答案 8 :(得分:0)

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

答案 9 :(得分: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之间的垂直空间量

答案 10 :(得分: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)
    ...
}

答案 11 :(得分:0)

这个问题已经很老了,但是我发现的壁橱里的东西是设置了额外的限制因素(所以围绕着&#34;周围的观点去了,一旦它失踪了就知道该做什么)< / p>

A  which you want to be     A
|  after setting B to gone  |
B                           C
|                               
C                               
  1. 将较低优先级(750)约束从C设置为A.
  2. 将B的顶部和底部约束(或左侧和右侧,如果您希望视图水平折叠)添加到NSLayoutConstraint数组bConstraints。这样做:
    1. 控制单击并从约束拖动到ViewController
    2. 将连接从插座更改为插座集合
    3. 名称为bConstraints
    4. 点击连接。这将在ViewController中创建@IBOutlet var bConstraints: [NSLayoutConstraint]!
    5. 要添加其他约束:从Storyboard中的约束拖动到@IBOutlet变量名称
  3. 然后隐藏B

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

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    
  5. 显然,越多越多的视图越复杂,因为每个视图都需要额外的约束

答案 12 :(得分:-2)

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

如果看不到,视图不一定占用空间!

我创建了一个ComboBox-Alike,其中ListView位于其他视图之上。我只在选择时可见:

enter image description here