使用自动布局时显示和隐藏视图

时间:2015-11-19 17:57:38

标签: ios swift autolayout xcode7 ios-autolayout

我有一些观点,我必须删除UIView,并让所有其他视图重新排列,不带此视图。我通常通过创建具有不同权重的多个约束来实现这一点,因此当我删除FromSuperView时,所有其他具有较低权重的约束开始工作并且所有内容都根据需要重新排列。

它工作得很好但是现在我必须显示和隐藏视图但是当我删除了FromSuperView时,该视图已经消失了所有约束......我不知道该做什么...我可以改变宽度和高度限制到对于我想要隐藏的视图为零...但问题是我必须在代码中硬编码高度并且我不喜欢它...

隐藏和展示UIViews的最佳方式是什么?类似于“已安装”属性,您可以在IB中设置,但可以从代码中设置。

4 个答案:

答案 0 :(得分:2)

当您从超级视图中删除视图时会丢失约束,您基本上可以将其用于视图中的任何对象,这样您就必须编写一些方法来添加到其他视图(以编程方式添加约束)或再次删除它。

根据我的隐藏视图的经验,您可以使用约束动画查看自身动画并将其向左,向右,向上或向下抛出。另外,要在用户互动中无法使用,您只需使用self.view.hidden = trueself.view.userInteractionEnabled = false将其停用即可。当你也更新视图时使用dispatch_async(),苹果喜欢编码标准的人:)。

使用动画隐藏视图:

            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.view.hidden = true // Or userInteractionEnable = false
                UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
                    self.reportView.alpha = 0
                    }, completion: nil)
            })

隐藏带约束的视图:

您需要创建约束IBOutlet以将常量与动画一起使用。

        self.someView.constant = -205 // Throw it off canaves
        UIView.animateWithDuration(1.0, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
            self.view.layoutIfNeeded()
            }, completion: { (finished: Bool)-> Void in
                self.someView.hidden = true
        })

让它看起来只是反过来做同样的想法。但不要removeFromSuperView(),除非你试图将它附加到First Responder或类似的东西。

答案 1 :(得分:2)

如果定位到iOS 9及更高版本,您可以尝试使用UIStackView。

我们可以想到保留约束的一种方法是在UIView上创建一个类别。

@interface UIView (ConstraintsPreserving)

@property (nonatomic, strong) NSMutableArray * preservedConstraints;

-(void)removeFromSuperViewPreservingConstriants;
-(void)addToSuperViewPreservingConstriants:(UIView *)superView;

@end

#import <objc/runtime.h>

@implementation UIView (ConstraintsPreserving)

@dynamic preservedConstraints;

-(void)setPreservedConstraints:(NSMutableArray *)object {
    objc_setAssociatedObject(self, @selector(preservedConstraints), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSMutableArray *)preservedConstraints {
    return objc_getAssociatedObject(self, @selector(preservedConstraints));
}

-(void)removeFromSuperViewPreservingConstriants
{
    if(!self.superview) return;

    self.preservedConstraints = [NSMutableArray new];
    [self.preservedConstraints addObjectsFromArray:[self constraints]];

    for (NSLayoutConstraint * constraint in self.superview.constraints) {
        if([constraint.firstItem isEqual:self] || [constraint.secondItem isEqual:self])
            [self.preservedConstraints addObject:constraint];
    }
    [self removeFromSuperview];
}

-(void)addToSuperViewPreservingConstriants:(UIView *)superView
{
    if(self.superview) return;

    [superView addSubview:self];
    [superView addConstraints:self.preservedConstraints];
    self.preservedConstraints = nil;
}

@end

PS:通过捕获这些约束中涉及的所有视图,强烈捕获约束。

答案 2 :(得分:0)

我不确定您的问题是否合适,但我做了几次,是为了确保您要隐藏的视图位于容器中。这样的容器应该有一个高度和宽度约束(这是你可能不喜欢它的地方)。然后,您可以在相关视图控制器中为这些约束中的每一个创建IBOutlet(控制从故事板中的约束拖动)。最后,您可以在viedidload中保存约束的初始值,稍后使用它从零切换到该值,无论它是什么。

答案 3 :(得分:0)

所以,我最终创建了IBOutlets来创建我想要隐藏的视图。我将宽度和高度约束设置为零,这样我隐藏了视图。我还设置了多个IBOutlets并改变了这些约束的优先级,所以我可以重新安排一些东西......

这是我发现的最佳方式。