18

次のコードを追加したので、アプリがこれを開くたびUITableViewControllerにクラッシュします。

 self.noArticlesView = [[UIView alloc] init];
 self.noArticlesView.translatesAutoresizingMaskIntoConstraints = NO;
 self.noArticlesView.backgroundColor = [UIColor colorWithRed:0.961 green:0.961 blue:0.961 alpha:1];

 [self.view addSubview:self.noArticlesView];

 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]];
 [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.noArticlesView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]];    

そして、それは私にこのエラーを与えます:

*キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: '-layoutSubviews の実行後も自動レイアウトが必要です。-layoutSubviews の UITableView の実装では、super を呼び出す必要があります。

私は一体何を間違っているのですか?tableView:numberOfRowsInSection:行が 0 のときにそのコードを呼び出します。

4

9 に答える 9

14

UIScrollView をサブクラス化していて、iOS 7 で同じエラー メッセージを受け取りました (8 ではありません)。

次のような方法で layoutSubviews をオーバーライドしていました。

- (void)layoutSubviews {
    [super layoutSubviews];
    // code to scroll the view
}

スーパーのlayoutSubviewsへの呼び出しをメソッドの最後に移動することで問題を解決しました。

- (void)layoutSubviews {
    // code to scroll the view
    [super layoutSubviews];
}
于 2015-02-14T02:00:23.930 に答える
2

同じ問題がありました。ビューを self.tableView に追加し、制約を使用しました。addSubview: を使用してテーブル ビューにビューを追加しないでください。ヘッダー、フッター、またはセルとして追加してください。

于 2014-09-29T09:41:03.467 に答える
2

[self.view layoutIfNeeded]

お役に立てれば

于 2014-11-25T13:14:22.613 に答える
1

また、テーブル ビューのマスク変換を無効にする必要があります。

于 2013-11-11T06:41:55.940 に答える
0

noArticlesView考えられる解決策は、 をテーブルに直接追加することではなくUITableView、 をコンテナー内に配置しUIView(最終的にコンテナー フレームに合わせてテーブル制約を設定します)、noArticlesView設定したものと同じ制約を使用してコンテナーに制約することです。コード内の同じ場所、つまり-tableView:numberOfRowsInSection: UITableViewDataSourceメソッド内です。簡単な例でテストしたところ、うまくいきました。
コードに適用する必要がある変更はUITableViewController、 を UIViewController に置き換え、コンテナー ビューを追加し (テーブルをビュー コントローラーのビューに正確に合わせたい場合を除きます。この場合、このビューはコンテナーです)、noArticleView を制約します。テーブルではなくコンテナに。私のコード例は、この回答の最後にあります。
問題の理由とこの解決策が機能する理由について説明できるように努めますが、私の説明の一部は推測に基づいているため、完全に正確ではないことを考慮してください.
まず、iOS でビュー階層のレンダリング プロセスがどのように機能するかについて簡単に説明します。レイアウト エンジンの最初のステップは、ビュー階層内のすべてのビューとサブビューのサイズと位置を決定することです。通常、これは、ビューとサブビューのサイズと位置を決定するために自動レイアウト制約が評価される反復アプローチで行われ、次に -layoutSubviews微調整のために各ビューのメソッドが呼び出されます。これは、制約が変更された後にレイアウトを変更できることを意味します。評価した。レイアウト エンジンが必要とするのは、-layoutSubviewsメソッドが制約を再度変更した場合、-[super layoutSubviews]反復プロセスを許可するには、再度呼び出す必要があります。これが発生しない場合、レイアウト エンジンは例外を発生させます。UITableView の場合、tableView:numberOfRowsInSection: メソッドが内部の UITableView layoutSubviews メソッド内のどこかで呼び出され、このメソッドは [super layoutSubviews] を呼び出さないと思います。そのため、テーブル データ ソース メソッドが内部テーブル制約を更新すると、メソッドの最後で例外がトリガーされます。テーブルに適用される唯一の制約はコンテナに対する外部制約であるため、レイアウトプロセスの最初の段階で評価されるため、私が提案するソリューションは機能しますが、テーブルデータソースメソッドで追加された制約はテーブルに関連していません。テーブルの外部のビュー (container および noArticlesView) に適用されるため、適用されません。



//
//  RootController.h

#import 

@interface RootController : UIViewController

@property (nonatomic,strong) IBOutlet UITableView *table;
@property (nonatomic,strong) IBOutlet UIView *container;

@end

//
//  RootController.m


#import "RootController.h"

@implementation RootController

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.

    UIView *_v = [[UIView alloc] init];
    _v.backgroundColor=[UIColor redColor];
    _v.translatesAutoresizingMaskIntoConstraints=NO;

    [self.container addSubview:_v];
    NSLayoutConstraint *_c1 = [NSLayoutConstraint constraintWithItem:_v
                                                            attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeTop multiplier:1.0 constant:20.0];
    NSLayoutConstraint *_c2 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20.0];
    NSLayoutConstraint *_c3 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20.0];
    NSLayoutConstraint *_c4 = [NSLayoutConstraint constraintWithItem:_v
                                                           attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.container attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20.0];
    [self.container addConstraints:@[_c1,_c2,_c3,_c4]];

    return 0;
}
于 2013-11-26T22:24:36.917 に答える