Remove Auto-Layout Constraints for Specific Object

前端 未结 6 465
走了就别回头了
走了就别回头了 2020-12-24 05:16

I have a UIImageView embedded in a UIView. My entire app uses AutoLayout, but I want to remove constraints for the

6条回答
  •  鱼传尺愫
    2020-12-24 05:36

    If you simply want to remove a view from a hierarchy, just call [theView removeFromSuperview]. Any constraints affecting it will also be removed.

    However, sometimes you might also want to put a view back, having temporarily removed it.

    To achieve this, I use the following category on UIView. It walks up the view hierarchy from a view v to some ultimate container view c (usually your view controller's root view) and removes constraints that are external to v. These are constraints that are siblings to v, rather than constraints that only affect v's children. You can hide v.

    -(NSArray*) stealExternalConstraintsUpToView: (UIView*) superview
    {
        NSMutableArray *const constraints = [NSMutableArray new];
    
        UIView *searchView = self;
        while(searchView.superview && searchView!= superview)
        {
            searchView = searchView.superview;
    
            NSArray *const affectingConstraints =
            [searchView.constraints filteredArrayUsingPredicate:
             [NSPredicate predicateWithBlock:^BOOL(NSLayoutConstraint *constraint, NSDictionary *bindings)
              {
                  return constraint.firstItem == self || constraint.secondItem == self;
              }]];
    
            [searchView removeConstraints: affectingConstraints];
            [constraints addObjectsFromArray: affectingConstraints];
        }
    
        return constraints;
    }
    

    The method passes back the removed constraints in an array that you can keep somewhere so that later on you can add the constraints back.

    Use it a bit like this…

    NSArray *const removedConstraints = [viewToHide stealExternalConstraintsUpToView: self.view];
    [viewToHide setHidden: YES];
    

    And later on, put the constraints back.

    As of iOS 8 you don't need to think about where the constraints should be put. Just use this…

    [NSLayoutConstraint activateConstraints: removedConstraints];
    [viewToHide setHidden: NO];
    

    With earlier versions of iOS you don't need to think hard about where to add the constraints back. Throw then in the controller's self.view. Provided constraints are in a superview of all the views that they affect, they will work.

    [self.view addConstraints: removedConstraints];
    [viewToHide setHidden: NO];
    

提交回复
热议问题