Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add View Hierarchy Traversal to Remove Constraints #4

Closed
wants to merge 10 commits into from

Conversation

rhgills
Copy link

@rhgills rhgills commented Jul 1, 2013

removeConstraintsFromApplicableSuperview:

Added removeConstraintsFromApplicableSuperview:, which traverses through all the superviews of the receiver to remove each passed constraint from the nearest superview that holds it. This means that you can remain blissfully unaware of which superview FLKAutoLayout is adding constraints to when constraining a view, yet still remove them by calling it on either of the views that you used to configure the constraints.

I discovered the need for this method when implementing a container view controller. When that container switches the single contained view controller it holds, I wanted to remove all constraints it configured on the previously contained view controller's view before removing it from the view hierarchy. In this case, I use it as follows:

- (void)makeViewControllerInactive:(UIViewController *)theViewController;
{
    [theViewController  willMoveToParentViewController:nil];

    // NB: There is no need to explicitly remove constraints applying to a view that you are removing from the view hierarchy. Constraints will be removed automatically when removing that view.
    [[inactiveViewController view] removeConstraintsFromApplicableSuperview:self.    activeViewControllerPositioningConstraints];
    self.activeViewControllerPositioningConstraints = nil;

    [[theViewController view] removeFromSuperview];
    [theViewController removeFromParentViewController];
}

When setting constraints on the activeViewController in updateViewConstraints, I populate the array of activeViewControllerPositioningConstraints.

Unit Tests

I also took the opportunity to add a unit test target and wrote some tests to drive out the implementation of removeConstraintsFromApplicableSuperview:. Hopefully this will encourage others to improve the test coverage going forward.

Repo Structure

And, as part of adding the unit test target, I messed with the repository directory structure a bit (hopefully for the better). I hope I'm not stepping on your toes too much here. Please do let me know your thoughts on both the organizational changes I made and the more substantial ones.

@floriankugler
Copy link
Owner

Hi Robert,

thanks a lot for your contribution.
I'm traveling atm, so it will be a bit until I get to this. But I have two points in the mean time:

  1. I think a method to remove constraints is a good idea in general, but why did you need it in your case? Why did you want to remove the constraints although you're removing the view from the view hierarchy anyway?
  2. Your use of the view controller containment API is not correct as described in the docs. The sequence is off, check here: Creating Custom Container View Controllers - Apple Developer

Thanks, Florian

On 02.07.2013, at 00:23, Robert Gilliam notifications@github.com wrote:

removeConstraintsFromApplicableSuperview:

Added removeConstraintsFromApplicableSuperview:, which traverses through all the superviews of the receiver to remove each passed constraint from the nearest superview that holds it. This means that you can remain blissfully unaware of which superview FLKAutoLayout is adding constraints to when constraining a view, yet still remove them by calling it on either of the views that you used to configure the constraints.

I discovered the need for this method when implementing a container view controller. When that container switches the single contained view controller it holds, I wanted to remove all constraints it configured on the previously contained view controller's view before removing it from the view hierarchy. In this case, I use it as follows:

  • (void)makeViewControllerInactive:(UIViewController *)inactiveViewController
    {
    [inactiveViewController willMoveToParentViewController:nil];
    [inactiveViewController removeFromParentViewController];

    [[inactiveViewController view] removeConstraintsFromApplicableSuperview:self. activeViewControllerPositioningConstraints];
    self.activeViewControllerPositioningConstraints = nil;

    [[inactiveViewController view] removeFromSuperview];
    [inactiveViewController didMoveToParentViewController:nil];
    }
    When setting constraints on the activeViewController in updateViewConstraints, I populate the array of activeViewControllerPositioningConstraints.

Unit Tests

I also took the opportunity to add a unit test target and wrote some tests to drive out the implementation of removeConstraintsFromApplicableSuperview:. Hopefully this will encourage others to improve the test coverage going forward.

Repo Structure

And, as part of adding the unit test target, I messed with the repository directory structure a bit (hopefully for the better). I hope I'm not stepping on your toes too much here. Please do let me know your thoughts on both the organizational changes I made and the more substantial ones.

You can merge this Pull Request by running

git pull https://github.com/rhgills/FLKAutoLayout remove-constraints
Or view, comment on, or merge it at:

#4

Commit Summary

Restructure Example
Add a workspace, update project
Add unit tests. Add view hierarchy traversal to remove constraints.
fix podspec
really fix podspec
add todo
revert podspec source url to upstream
bump the version due to changing repo structure
Tests now use an actual UIWindow to exercise more autolayout machinery.
Added a test exercising removal from an indirect superview when the constraint applies to that superview.
File Changes

R Classes/FLKAutoLayoutPredicateList.h (0)
R Classes/FLKAutoLayoutPredicateList.m (0)
R Classes/UIView+FLKAutoLayout.h (4)
R Classes/UIView+FLKAutoLayout.m (43)
R Classes/UIView+FLKAutoLayoutPredicate.h (0)
R Classes/UIView+FLKAutoLayoutPredicate.m (0)
R Example/Classes/ALEAppDelegate.h (0)
R Example/Classes/ALEAppDelegate.m (0)
R Example/Classes/ALEViewController.h (0)
R Example/Classes/ALEViewController.m (0)
M Example/FLKAutoLayoutExample.xcodeproj/project.pbxproj (92)
D Example/FLKAutoLayoutExample/FLKAutoLayoutExample-Info.plist (42)
R Example/Other Sources/FLKAutoLayoutExample-Prefix.pch (0)
R Example/Other Sources/main.m (0)
R Example/Resources/Default-568h@2x.png (0)
R Example/Resources/Default.png (0)
R Example/Resources/Default@2x.png (0)
A Example/Resources/FLKAutoLayoutExample-Info.plist (39)
R Example/Resources/en.lproj/InfoPlist.strings (0)
M FLKAutoLayout.podspec (4)
A Tests/FLKAutoLayout Tests.xcodeproj/project.pbxproj (342)
A Tests/Other Sources/iOS Tests-Prefix.pch (8)
A Tests/Resources/en.lproj/InfoPlist.strings (2)
A Tests/Resources/iOS Tests-Info.plist (22)
A Tests/Tests/UIView+FLKAutoLayoutTests.m (92)
A todo.taskpaper (3)
Patch Links:

https://github.com/dkduck/FLKAutoLayout/pull/4.patch
https://github.com/dkduck/FLKAutoLayout/pull/4.diff

@rhgills
Copy link
Author

rhgills commented Jul 7, 2013

Both good points! Say there are two views, with A the superview of B. A holds some constraints that apply to B. I had assumed that the constraints affecting B would not automatically be removed from A when removing B from the view hierarchy. Some experimentation shows that this is not the case and they are automatically removed. Turns out I don't need this in my case! Thanks; it's always nice to delete some code.

And thanks for the tip re: the containment API. I found out I was using it wrong shortly before seeing your post. I'll correct it above as to not mislead anyone who happens to read it.

Enjoy your travels!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants