Interface Builder에서 배치한 뷰의 클래스를 나중에 변경하는 방법

Interface Builder에서 한 번 배치한 뷰를 다른 클래스로 바꾸고 싶은 경우가 있습니다. 자작의 서브 클래스로 옮겨놓는다면, 클래스의 지정을 변경하면 됩니다만, UIView 를 해 버린 후라면 매우 귀찮은 작업이 됩니다.

이것을 피하고 싶다면 내용의 XML을 직접 편집 할 수밖에 없습니다 (개인적으로 이것을 xib의 개복 수술이라고 부릅니다).

UIView를 UIImageView로 바꾸기



우선 간단한 예로서 UIImageViewUIView 로 옮겨놓는 것을 생각해 봅시다.



단순히 클래스의 지정을 UIImageView 로 변경하는 것도 손입니다. 그러나 이것으로는 IB상에서의 취급은 단지 UIImageView 와 변함없이, UIView 의 설정등을 할 수 없습니다.



여기서는 XML을 편집하여 클래스를 바꿉니다. 그렇다고해도 XML의 서식을 파악하고 있는 것은 아니기 때문에, 우선은 치환하고 싶은 클래스 image 를 배치해 보겠습니다.



그런 다음 xib(또는 스토리보드) 파일을 XML로 엽니다. 이렇게 하려면 왼쪽 열의 Project Navigator에서 원하는 파일을 마우스 오른쪽 버튼으로 클릭하고 Open As > Source Code를 선택합니다.



표시된 XML에서 대체할 클래스와 대체할 클래스가 어디에 있는지 찾습니다. 요소가 많아 찾기 어려운 경우는 view에 붙은 ID(오른쪽 컬럼의 Identity inspector에 Object ID로서 표시됩니다)로 검색하면 편합니다.

여기서 중요한 것은 "id", "frame"및 "constraints"입니다.



이러한 요소를 UIImageView 측에 복사하고 UIImageView 쪽은 삭제합니다.



Project Navigator에서 파일을 다시 마우스 오른쪽 버튼으로 클릭하고 Open As> Interface Builder XIB Document를 선택하여 IB에서 엽니 다.

문제가 없으면 아래 그림과 같이 예상대로 결과를 얻을 수 있습니다. XML 편집을 잘못하면 최악의 파일을 열 때마다 Xcode가 충돌합니다.



UITableViewCell을 UICollectionViewCell로 바꾸기



보다 복잡한 예로서 UIViewUITableViewCell 로 옮겨놓는 것을 생각합니다. 셀 위에 배치한 요소는 그대로, 근원만 클래스를 변경합니다. 복잡한 뷰 계층 구조와 Auto Layout을 설정한 경우 처음부터 다시 작성하지 마십시오.

여기에서는 알기 쉽게 하기 위해, 아래와 같이 UICollectionViewCell 바로 아래에 뷰가 하나 놓여져 있는 단순한 구조를 생각합니다.



TableViewCell의 XML은 다음과 같습니다.

TableViewCell.xib
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="zdF-YS-G3Z">
            <rect key="frame" x="0.0" y="0.0" width="320" height="88"/>
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zdF-YS-G3Z" id="3eA-Vz-neI">
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6HF-V6-sxv" userLabel="Image View">
                        <rect key="frame" x="8" y="8" width="72" height="72"/>
                        <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
                        <constraints>
                            <constraint firstAttribute="height" constant="72" id="8lk-Uc-lxx"/>
                            <constraint firstAttribute="width" constant="72" id="G96-X2-EQ8"/>
                        </constraints>
                    </view>
                </subviews>
                <constraints>
                    <constraint firstItem="6HF-V6-sxv" firstAttribute="top" secondItem="3eA-Vz-neI" secondAttribute="top" constant="8" id="PlM-tb-ObS"/>
                    <constraint firstItem="6HF-V6-sxv" firstAttribute="leading" secondItem="3eA-Vz-neI" secondAttribute="leading" constant="8" id="XlX-fl-gER"/>
                </constraints>
            </tableViewCellContentView>
            <point key="canvasLocation" x="271" y="133"/>
        </tableViewCell>
    </objects>
</document>

반면 CollectionViewCell은 다음과 같습니다.

CollectionViewCell.xib
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="KEu-Vi-azp">
            <rect key="frame" x="0.0" y="0.0" width="320" height="88"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
                <rect key="frame" x="0.0" y="0.0" width="320" height="88"/>
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zjc-6s-snt" userLabel="Image View">
                        <rect key="frame" x="8" y="8" width="72" height="72"/>
                        <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
                        <constraints>
                            <constraint firstAttribute="width" constant="72" id="VjM-p5-jxX"/>
                            <constraint firstAttribute="height" constant="72" id="qmW-i8-JdR"/>
                        </constraints>
                    </view>
                </subviews>
                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
            </view>
            <constraints>
                <constraint firstItem="Zjc-6s-snt" firstAttribute="leading" secondItem="KEu-Vi-azp" secondAttribute="leading" constant="8" id="3JU-Lw-Ko2"/>
                <constraint firstItem="Zjc-6s-snt" firstAttribute="top" secondItem="KEu-Vi-azp" secondAttribute="top" constant="8" id="nW8-az-cXE"/>
            </constraints>
            <point key="canvasLocation" x="253" y="188"/>
        </collectionViewCell>
    </objects>
</document>

상기에서는 알기 어렵기 때문에, 중요한 부분만 빼내 보면 이하와 같이 됩니다. TableViewCell과 ContentViewCell은 구조가 약간 다르다는 것을 알 수 있습니다.





이것을 참고로, 이하의 순서로 TableViewCell로부터 CollectionViewCell로의 이식이 가능합니다.
  • contentView 의 ID 를 collectionViewCell 의 ID 에 맞추기
  • tebleViewCellContentView 의 아래 tebleViewCellContentView 를collection view의 subviews 아래에 복사
  • <view key="contentView"> 의 아래 tebleViewCellContentViewconstraints 아래에 복사

  • collection view에서는 subview와 constraint가 있는 계층구조가 다르다는 점에 주의가 필요합니다.

    좋은 웹페이지 즐겨찾기