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


79

我正在开发适用于iOS的应用,并且正在使用自动布局打开的情节提要。我的一个视图控制器具有一组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;

如何将按钮的高度设置为零?
cahn 2013年

我尝试过这样的事情:UIButton * b; CGRect frameRect = b.frame; frameRect.size.height = 0; b.frame = frameRect; 没有运气:(
elbuild

我知道这是一个非常老的问题,但是如果您使用自动版式,则有关将帧设置为0的更新无济于事。您必须将高度限制设置为0
wyu

Answers:


40

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

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

11
迅捷版本:self.view.addConstraint(NSLayoutConstraint(item: self.captchaView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0))
iStar

1
这应该是答案
Rick Royd Aban

2
如果我不知道所需视图的实际高度(例如稍后渲染的容器视图)怎么办?
A. Petrov

非常感谢您的出色回答!对于某人可能需要它。我出错了Unable to simultaneously satisfy constraints。虽然我已经对该视图有限制。我的解决它stackoverflow.com/a/38625419/1270901
内文陈

@iStar我已经使用相同的代码,但它不工作... stackoverflow.com/questions/45454992/...
桑杰Mangaroliya

20

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

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

隐:

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

能见度:

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

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

文件


实际上似乎是一个非常好的解决方案,但值得注意的是它需要iOS9 +。
user3533716 '16

我使用了您出色的解决方案(为您+1,非常感谢!),但是我通过IBOutlet直接连接了要显示和隐藏的视图,因此我只需要键入一行代码即可!:)
克里斯蒂娜·德·里托

1
这个答案实际上是不正确的。Android View.GONE删除UI上的视图。例如,如果将View.GONE设置为元素,则该视图下方的视图将上移。因此,您的建议只是隐藏等于View.HIDE的视图。看看这个答案:stackoverflow.com/questions/11556607/...
额敏德尼兹

我没有在android api上搜索...但是我是移动开发人员,所以我知道技工...在带有布尔标志视图的Android中可以查看还是不查看(已消失,可见)如果从ui中删除,则很难再次添加...但在ios中,它的布局中没有空格。...此外,还有正式的ios隐藏属性正在发生... UIStackview隐藏属性(如android View.Gone
Ucdemir

16

向视图添加高度约束,如下所示:在此处输入图片说明

然后在viewController文件中为高度约束设置出口,如下所示:在此处输入图片说明

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

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

1
等高的高度很烂,我使用相等的高度和乘数,例如占父视图的25%,有什么例子吗?
user924

8

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

SWIFT 4:

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

这是一个表格单元格示例,只需将其放入其中Stack view并为GONE孩子获取物品。

在此处输入图片说明



1

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

}


1

这个问题已经很老了,但我发现壁橱里的东西正在设置其他约束(因此,“消失”视图周围的视图知道丢失后该怎么做)

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. 点击连接。这将@IBOutlet var bConstraints: [NSLayoutConstraint]!在您的ViewController中创建一个
    5. 要添加其他约束,请执行以下操作:从情节提要中的约束拖到@IBOutlet变量名称
  3. 然后隐藏B

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

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    

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


如果您解释了为什么无法实施的话,这会有所帮助
wyu

第二点。我在Xamarin工作。仍然没有找到解决此问题的方法。不知道如何构造带有B约束的NSLayoutConstraint数组。我认为这是通过编程完成的,很高兴看到它的代码。在我看来,您的方法似乎是解决此问题的最合理方法,但是用伪代码不容易实现
Gustavo Baiocchi Costa

我没有用过Xamarin。在XCode中完成的方式是:按住Ctrl键单击并从约束中拖动到ViewController(这与您用xcode创建IBOutlet的方式类似)。在出现的弹出窗口(外观类似于i.stack.imgur.com/JegLK.png)中,将“连接”下拉菜单从Outlet更改为Outlet Collection。对于其他约束,ctrl直接拖到变量名。我可以在今天晚些时候(约8个小时内)上传场景截图
wyu

所以NSLayoutConstraint数组是插座集合,在这里有点迷路了哈哈,
谢谢您抽出宝贵

是的,我将更新答案以使其更加清晰。因此,该解决方案对您有用吗?
wyu

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时,代码都会中断。我有一个在float view_idLoad中设置的float _optionalHeight字段,因此它始终是最新的。


0

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


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


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)
    ...
}

-3

setHidden:TRUE / FALSE与Android View.GONE / VISIBLE最接近。

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

我用其他视图之上的ListView制作了一个ComboBox-Alike。我仅在选择时可见:

在此处输入图片说明


您忘记了在android中我们也有view.invisible ... view.gone与setHidden不相似...其view.invisible与setHidden类似
Nav
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.