33

Suppose I use Interface Builder to create UI in Storyboard with Auto Layout. Can I copy or move some constraints from one view to another?

kelin
  • 9,553
  • 6
  • 63
  • 92

3 Answers3

18

If you are using interface builder, some constraints will be automatic copied if you use the cmd-c or edit/copy: the ones that include the copying view hierarchy. Otherwise, no, you can't. Copy the whole view if you want to preserve the constraints.

iOS Developer
  • 3,393
  • 2
  • 38
  • 56
  • Thank you for answer, but I need to change view type in interface builder. That why I ask how to copy constraints. Copying the view will not help in my situation. – kelin Feb 20 '15 at 10:04
  • 1
    This is a different question, see my answer here please: http://stackoverflow.com/a/28626319/1758701 – iOS Developer Feb 20 '15 at 10:08
  • 1
    I changed view type by editing source code of the Storyboard. – kelin Feb 20 '15 at 10:11
  • 1
    Well, seems like this is the proper answer. – kelin Feb 26 '15 at 15:44
  • 1
    can we copy constraints from one view to another view programmatically ? – MANISH PATHAK Feb 22 '17 at 18:33
  • @iOSdev can i copy the constraints prgramatically to set in a view controller, actually i am making a form by generating some text box and labels and want to save in a view controller as a form any idea how to implement this – Xcodian Solangi Dec 20 '17 at 05:09
  • @XcodianSolangi, No, you have to create and add new constraints if either the first either the second view is different. – Iulian Onofrei Apr 20 '18 at 11:30
17

Here's my hack to get ALL the constraints to copy: I have a small view within my main view that I want to copy over to another view controller, in order to do this I copy over the entire main view into the new view controllers main view. I then drag my small view (on side hierarchy) into the main view of my new controller and then just deleted the old main view that I don't need. This way you keep all the constraints for the items within the small view.

Hope this helps :)

Trianna Brannon
  • 1,196
  • 10
  • 12
16

You can if you understand and learn how the XML of the .xib files works. I got pretty used to them and so I was able to move a view with its constraints into another view.

I'll try to explain it step by step:

  1. Create an outlet for it: myView
  2. Right click the .xib file > Open As > Source Code or open it in another editor (e.g. Sublime Text)
  3. Search myView and you'll find something like:

    <outlet property="myView" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
    

    and copy the destination attribute's value

  4. Search the copied id (i5M-Pr-FkT) and one of the results will be a view tag:

    <view contentMode="scaleToFill" id="i5M-Pr-FkT"> <!-- 1 -->
        ...
    </view>
    
  5. Cut and paste this whole view tag in the needed view's subviews tag:

    <view contentMode="scaleToFill" id="Ovp-8Y-qHZ"> <!-- 2 -->
        <subviews>
            <view contentMode="scaleToFill" id="i5M-Pr-FkT"> <!-- 1 -->
                ...
            </view>
        </subviews>
    </view>
    
  6. Continue searching for the copied id and you'll find some constraints that have it like:

    <constraint firstItem="w7M-JQ-JWD" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="EwH-B1-XWY"/>
    
  7. You need to move this into the constraints tag of the lowest common ancestor of both superviews (the old one and the new one):

    <view contentMode="scaleToFill" id="rK2-sE-P0d"> <!-- 3 -->
        <subviews>
            <view contentMode="scaleToFill" id="Ovp-8Y-qHZ"> <!-- 2 -->
                <subviews>
                    <view contentMode="scaleToFill" id="i5M-Pr-FkT"> <!-- 1 -->
                        ...
                    </view>
                </subviews>
            </view>
        </subviews>
        <constraints>
            <constraint firstItem="w7M-JQ-JWD" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="EwH-B1-XWY"/>
        </constraints>
    </view>
    
Iulian Onofrei
  • 7,489
  • 8
  • 59
  • 96
  • Great answer! I see you searching view by `id`, and what if I want to *copy* that view, not *cut* and paste? I suppose the `id` should be unique. Should it be generated by some specific rules, or it's would be enough to randomly modify it? – kelin Apr 06 '17 at 10:43
  • Yes, the `id` should be unique per `.xib` file, so it can't be the same even for a `view` and a `constraint`. I can't guarantee you, but from what I saw, it's completely random, but to be safe, keep it in the same format: `3 chars - 2 chars - 3 chars`. You can also add a new view, detect it by either positioning it at the top of the view hierarchy so you'll find it easier, either by staging the file before adding it, copy its `id`, remove the view and use that `id`. – Iulian Onofrei Apr 06 '17 at 10:47
  • Also, please accept this answer instead if it helped you, as the current one isn't achieving what you asked for. – Iulian Onofrei Apr 06 '17 at 10:47
  • I don't know, your answer provides more insight... But I just wanted to copy constraints, not the whole view. And the accepted answer is much more simple: copy view in Interface Builder, then change it's type in source code. So my final resolution is not to change the accepted answer and wait a while. – kelin Apr 06 '17 at 10:54
  • Oh, sorry. But you can still do that by changing the `XML` directly, which provides greater control than the `Interface Builder`'s automatic shenanigans. You'll just use the final step `7` from my answer and/or change the `firstItem` / `secondItem` attributes' values accordingly. Let me know if you need me to explain it in an edit. – Iulian Onofrei Apr 06 '17 at 10:59
  • Sure, as Storyboards are `XML` too and I think they contain multiple xib structures. – Iulian Onofrei Apr 13 '17 at 11:28
  • 2
    Great, I was able to copy several views, just be sure to check the IDs that must be unique to each constraint and views. – Nicoli Dec 05 '19 at 17:37