web-dev-qa-db-ja.com

Xcode6のUITableViewでの自動サイズ変更の問題

UITableviewのxcode6で自動サイズ変更を使用していますが、正しく機能していません。自動サイズ変更を使用したい。ストーリーボードのUITableviewControllerクラスの静的セルにテキストフィールドを追加しました。横向きまたは縦向きの画面を超えたテキストフィールド。プロジェクト全体が自動サイズ変更である自動レイアウトを使用したくありません。 Textfield

デモプロジェクト

22
Vivek Yadav

私は最近同じ問題を抱えていました。 UITableViewCellのコンテンツビューにラベルを追加し、非表示にするたびに(x >> 320)。問題はソースコードXMLにあることに気づきました。

XMLは次のとおりです。

<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="InvoiceCell" rowHeight="60" id="B9T-xx-TCx" customClass="InvoiceCell"> 
    // My custom cell is 60 height
    <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> 
    // Wrong Autoresizing
    <autoresizingMask key="autoresizingMask"/> 
    <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="B9T-xx-TCx" id="nvL-MG-mGs">
        //No rect frame and wrong autoresizing mask
        <autoresizingMask key="autoresizingMask"/>

私の問題を解決するには、「tableViewCell」と「tableViewCellContentView」を次のように変更するだけです。

<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="InvoiceCell" rowHeight="60" id="B9T-xx-TCx" customClass="InvoiceCell"> 
    //Add/change this 2 lines in <tableViewCell>
    <rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES"/>

そして

<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="B9T-xx-TCx" id="nvL-MG-mGs">
    //Add/change this 2 lines in <tableViewCellContentView>
    <rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES"/>

だから、問題は解決しました!これが皆さんのお役に立てば幸いです。

11
rcmstark

Xcode 6.xibと.storyboardの処理の問題です。間もなく、Xcodeは不適切なフレームをテーブルビューセルとそのcontentViewに設定します。もう少し詳しく説明させてください。

自動サイズ変更マスクのしくみ

基本的に、ビューframeをそのスーパービューのframeにバインドします。どのマージンと寸法を柔軟にし、何を固定するかを指定できます。スーパービューの境界が変更されると、自動サイズ変更の仕様に従ってビューの境界も変更されます。これは、実行時だけでなく、Xcode InterfaceBuilderでも発生しました。サブビューを使用していくつかのビューを作成し、サブビューにさまざまな自動サイズ変更オプションを設定して、マスタービューのサイズを変更してみてください。 Xcodeでサブビューのサイズが変更されていることがわかります。便利ですね

エラーの原因

テーブルビューのセルをiPhoneストーリーボードからiPadストーリーボードにコピーした後、まったく同じ問題を最初に発見しました。 .storyboardファイルを少し掘り下げた後、セルとそのcontentViewにはまだ.storyboardにフレーム320x91(iPadのサイズは768x91ではなく)がありますが、画面上とインスペクターでは両方とも正しいサイズであることがわかりました。これは、実際のシリアル化されたデータと視覚的表現の間の不整合です。

<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="91" sectionHeaderHeight="22" sectionFooterHeight="22" id="nKc-Lp-03y">
    <rect key="frame" x="0.0" y="58" width="768" height="901"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <prototypes>
        <tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="PriceEvaluateCell" rowHeight="91" id="cis-7J-9wV" customClass="PriceEvaluateCell">
            <rect key="frame" x="0.0" y="434" width="320" height="91"/>
            <!-- note how small frame is! But it is drawn with iPad width -->
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="cis-7J-9wV" id="cYU-lI-DGN">
                <rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
                <!-- here is same issue -->
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="TItle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="AOE-zL-Dv0">
                        <rect key="frame" x="9" y="3" width="305" height="21"/>
                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                        <!-- this view draws OK, it has small size, left alignment and flexible right margin -->
                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                        <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                        <color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                    </label>
                    <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="FGPrice" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="wPa-dC-JzV">
                        <rect key="frame" x="623" y="20" width="104" height="21"/>
                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                        <!-- this is bad view, it has flexible LEFT and will misplace every time you open the file -->
                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                        <color key="textColor" red="0.40000000600000002" green="1" blue="0.40000000600000002" alpha="1" colorSpace="calibratedRGB"/>
                        <color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                    </label>
                </subviews>
            </tableViewCellContentView>
            <connections>
                <!-- ... -->
            </connections>
        </tableViewCell>
    </prototypes>
    <connections>
        <!-- ... -->
    </connections>
</tableView>

したがって、iPadのサイズ(たとえば、x = "624" y = "19" width = "80" height = "21")と柔軟な左マージンに応じてセルサブビューframeを設定するとします。セルの境界を超えて内部的に視覚的にまだ正しく設定されているように見えます。ストーリーボードを保存してファイルから再読み込みすると、セルとそのcontentViewは自動的に320x91から768x91にサイズ変更され、自動サイズ変更によるそのサブビューは自動的に右端に移動します。

それでは、あなたのケースを見てみましょう。幅が柔軟なテキストフィールドがあります。そして、プロジェクトを開くたびに、そのフレームはどんどん広くなっていきます。保存された幅と視覚的な幅の間に同じ矛盾があるように見えます。プロジェクトの.storyboardを開いた後、テーブルビューセルとそのcontentViewの両方にframeがまったく指定されていないことがわかります。したがって、あなたの場合、XcodeはセルとそのcontentViewの両方に非常に小さなフレームを暗黙的に設定していると言えます。

それが内部の様子です。

<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="246" sectionHeaderHeight="22" sectionFooterHeight="22" id="zuY-va-uVD">
    <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <sections>
        <tableViewSection id="KFU-cy-GoW">
            <cells>
                <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="245" id="WCc-Ec-YKn">
                <!-- note there is no frame at all -->
                    <autoresizingMask key="autoresizingMask"/>
                    <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WCc-Ec-YKn" id="DtD-vs-Xwy">
                        <!-- and here too -->
                        <autoresizingMask key="autoresizingMask"/>
                        <subviews>
                            <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="autorsizing" borderStyle="roundedRect" minimumFontSize="17" id="NCA-qk-Isa">
                                <!-- and here frame is already went wrong... -->
                                <rect key="frame" x="60" y="108" width="900" height="30"/>
                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
                                <color key="backgroundColor" red="0.89019607840000003" green="0.89019607840000003" blue="0.89019607840000003" alpha="1" colorSpace="calibratedRGB"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits"/>
                            </textField>
                        </subviews>
                    </tableViewCellContentView>
                </tableViewCell>
            </cells>
        </tableViewSection>
    </sections>
    <connections>
        <outlet property="dataSource" destination="1kU-E8-zzp" id="pca-5d-SRg"/>
        <outlet property="delegate" destination="1kU-E8-zzp" id="WxC-Qa-ToS"/>
    </connections>
</tableView>

直し方

最終的な解決策はまだ見つかりませんが、バグを回避することはできます。 Xcode自体が適切なフレームを設定できない場合は、手動で設定できます。任意のテキストエディタ(プレーンXML)でストーリーボードを開き、フレームを修正します。

<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="246" sectionHeaderHeight="22" sectionFooterHeight="22" id="zuY-va-uVD">
    <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
    <sections>
        <tableViewSection id="KFU-cy-GoW">
            <cells>
                <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="245" id="WCc-Ec-YKn">
                    <autoresizingMask key="autoresizingMask"/>
                    <!-- we insert the correct frame (exact size we can get from xcode editor, which draws it properly) -->
                    <rect key="frame" x="0.0" y="0.0" width="320" height="245"/>
                    <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WCc-Ec-YKn" id="DtD-vs-Xwy">
                        <!-- and here we do the same -->
                        <rect key="frame" x="0.0" y="0.0" width="320" height="244"/>
                        <autoresizingMask key="autoresizingMask"/>
                        <subviews>
                            <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="autorsizing" borderStyle="roundedRect" minimumFontSize="17" id="NCA-qk-Isa">
                                <!-- set any size that is smaller than parent frame. You will be able to change it with Xcode later -->
                                <rect key="frame" x="60" y="108" width="200" height="30"/>
                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
                                <color key="backgroundColor" red="0.89019607840000003" green="0.89019607840000003" blue="0.89019607840000003" alpha="1" colorSpace="calibratedRGB"/>
                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                <textInputTraits key="textInputTraits"/>
                            </textField>
                        </subviews>
                    </tableViewCellContentView>
                </tableViewCell>
            </cells>
        </tableViewSection>
    </sections>
    <connections>
        <outlet property="dataSource" destination="1kU-E8-zzp" id="pca-5d-SRg"/>
        <outlet property="delegate" destination="1kU-E8-zzp" id="WxC-Qa-ToS"/>
    </connections>
</tableView>

次に、Xcodeを閉じ、エディターからストーリーボードを保存して、Xcodeを再度開きます。出来上がり!テキストフィールドはその狂った方法を去り、今では期待通りに動作します。

31
Cemen

これを何時間もいじった後、cellForRowAtIndexPath ..でフレームを手動で設定しました。

私の状況では、私が持っていたラベルは常にセルの右端から8ポイント離れているはずでした...それを実行すると、ラベルが消えてしまいます。そこで、cellForRowAtIndexPathに、フレームを修正するための小さな「ハック」を追加しました...

if (cell.weight.frame.Origin.x != cell.frame.size.width - 138) {
    CGRect frame = cell.weight.frame;
    frame.Origin.x = cell.frame.size.width - 138;
    cell.weight.frame = frame;
}

その場合の138は、ラベルの幅(131)に、セルの右側から必要なパディング(7)を加えたものです。

それは正確にはきれいではありませんが、私にとってはうまくいきます!

1
tcd