63

動的であるため、セルの高さの合計に基づいて、テーブルビューの高さを別のビューコントローラーから変更したいと考えています。それはまったく可能ですか?ありがとう

アドオン:

私が基本的に持っているのは、画面の半分にコンテナビューを持つ UserProfileViewController です。そこで、他のさまざまなビューコントローラーを追加します。

ここに画像の説明を入力

ここに画像の説明を入力

ウォールボタンの場合、これはビューコントローラーを追加する方法であり、それはその後のテーブルビューです:

- (IBAction)wallButtonPressed:(id)sender
{
    //Check if there is an instance of the viewcontroller we want to display. If not make one and set it's tableview frame to the container's view bounds
    if(!_userWallViewController) {
        self.userWallViewController = [[WallViewController alloc] init];
//        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;

    }

    [self.userWallViewController.containerView addSubview:self.userWallViewController.activityFeedTableView];
    //If the currentviewcontroller adn it's view are already added to the hierarchy remove them
    [self.currentViewController.view removeFromSuperview];
    [self.currentViewController removeFromParentViewController];

    //Add the desired viewcontroller to the currentviewcontroller
    self.currentViewController = self.userWallViewController;

    //Pass the data needed for the desired viewcontroller to it's instances
    self.userWallViewController.searchURLString = [NSString stringWithFormat:@"event/user/%@/", self.userID];
    self.userWallViewController.sendCommentURLString = [NSString stringWithFormat:@"event/message/%@", self.userID];

    [self.userWallViewController.activityFeedTableView reloadData];

    self.userWallViewController.totalCellHeight = ^(float totalCellHeight){

        self.scrollView.contentSize = CGSizeMake(320.0, totalCellHeight);
        CGRect newFrame = self.userWallViewController.containerView.frame;
        newFrame.size.height = totalCellHeight + 33.0;
        self.userWallViewController.containerView.frame = newFrame;

        self.userWallViewController.activityFeedTableView.frame = self.containerView.bounds;
    };

    //Add this containerview to the desired viewcontroller's containerView
    self.userWallViewController.containerView = self.containerView;


    //Add the needed viewcontroller and view to the parent viewcontroller and the containerview
    [self addChildViewController:self.userWallViewController];
    [self.containerView addSubview:self.userWallViewController.view];

    //CLEAN UP THE CONTAINER VIEW BY REMOVING THE PREVIOUS ADDED TABLE VIEWS
    [self.userFansViewController.userSimpleTableView removeFromSuperview];
    [self.fanOfViewController.userSimpleTableView removeFromSuperview];
    [self.userPublishedMovellaListViewController.gridView removeFromSuperview];

    [self.userPublishedMovellaListViewController removeFromParentViewController];

    self.userPublishedMovellaListViewController = nil;
}

そしてそのviewcontrollerでは、これが私のテーブルビューを初期化する場所です:

-(UITableView *)activityFeedTableView
{
    if (!_activityFeedTableView) {
        _activityFeedTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 850.0) style:UITableViewStylePlain];
    }
    return _activityFeedTableView;
}

セルの高さの合計を計算していますが、問題は、テーブルビューのゲッターが呼び出された後にセルの高さメソッドが呼び出されることです。したがって、すべてのセルに対してセルの高さメソッドがいつ実行されたかを知るには、何らかの方法が必要です。その後、テーブルビューのサイズを変更できます。ありがとう

4

8 に答える 8

174

テーブルビューの内容に基づいてテーブルの高さを変更するシステム機能はありません。そうは言っても、コンテンツに基づいて、特にテーブルビューの高さに基づいて、テーブルビューの高さをプログラムで変更することは可能contentSizeです (手動で高さを自分で計算するよりも簡単です)。詳細のいくつかは、iOS 6 の一部である新しい自動レイアウトを使用しているかどうかによって異なります。

ただし、テーブル ビューの基になるモデルを で構成していると仮定すると、テーブル ビューのviewDidLoad高さを調整したい場合は、 でこれを行うことができますviewDidAppear

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self adjustHeightOfTableview];
}

同様にreloadData、テーブルビューに対して a (または行の追加または削除) を実行したことがある場合adjustHeightOfTableViewは、そこにも手動で呼び出すことを確認する必要があります。たとえば、次のようになります。

- (IBAction)onPressButton:(id)sender
{
    [self buildModel];
    [self.tableView reloadData];

    [self adjustHeightOfTableview];
}

そこで問題は、私たちが何をすべきかadjustHeightOfTableviewです。残念ながら、これは iOS 6 の自動レイアウトを使用するかどうかの機能です。ストーリーボードまたは NIB を開いて「ファイル インスペクター」に移動することで、自動レイアウトがオンになっているかどうかを確認できます (たとえば、option+ command+を押す1か、右側のパネルの最初のタブをクリックします)。

ここに画像の説明を入力

autolayout がオフになっているとしましょう。その場合、それは非常に簡単で、テーブルビューの をadjustHeightOfTableview調整するだけframeです:

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the frame accordingly

    [UIView animateWithDuration:0.25 animations:^{
        CGRect frame = self.tableView.frame;
        frame.size.height = height;
        self.tableView.frame = frame;

        // if you have other controls that should be resized/moved to accommodate
        // the resized tableview, do that here, too
    }];
}

ただし、自動レイアウトがオンの場合、テーブルビューadjustHeightOfTableviewの高さの制約が調整されます。

- (void)adjustHeightOfTableview
{
    CGFloat height = self.tableView.contentSize.height;
    CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;

    // if the height of the content is greater than the maxHeight of
    // total space on the screen, limit the height to the size of the
    // superview.

    if (height > maxHeight)
        height = maxHeight;

    // now set the height constraint accordingly

    [UIView animateWithDuration:0.25 animations:^{
        self.tableViewHeightConstraint.constant = height;
        [self.view setNeedsUpdateConstraints];
    }];
}

この後者の制約ベースのソリューションが自動レイアウトで機能するためには、最初にいくつかのことを処理する必要があります。

  1. ここでボタンのグループの中央のボタンをクリックして、テーブルビューに高さの制限があることを確認してから、高さの制限を追加することを選択します。

    高さ制限を追加

  2. IBOutlet次に、その制約に を追加します。

    IBOutlet を追加

  3. テーブルビューのサイズをプログラムで調整する場合に競合しないように、他の制約を調整してください。私の例では、テーブルビューには画面の下部にロックする末尾のスペース制約がありました。そのため、特定のサイズでロックされるのではなく、値以上になるようにその制約を調整する必要がありました。テーブルビューの高さと上部がその日を支配するように、優先度を低くします。

    その他の制約を調整する

    ここで他の制約を使用して何を行うかは、テーブルビューの下の画面にある他のコントロールに完全に依存します。いつものように、コンストレイントの処理は少し厄介ですが、状況の詳細はシーンに他に何があるかに完全に依存しますが、確実に機能します。しかし、うまくいけば、あなたはアイデアを得るでしょう。要するに、autolayout を使用する場合は、テーブルビューの高さの変化に対応できるように、他の制約 (存在する場合) を柔軟に調整してください。

ご覧のとおり、自動レイアウトを使用していない場合は、テーブルビューの高さをプログラムで調整する方がはるかに簡単ですが、使用している場合に備えて、両方の代替案を提示します。

于 2013-01-09T03:51:57.100 に答える
21

xib またはストーリーボードでセルを作成します。アウトレットの内容を教えてください。CellForRowAtIndexPath で呼び出すようになりました。例えば。コメントのラベル テキストに従ってセルの高さを設定する場合。 ここに画像の説明を入力

そのため、commentsLbl.numberOfLine=0; を設定します。ここに画像の説明を入力

そのため、commentsLbl.numberOfLine=0; を設定します。

次にViewDidLoadで

 self.table.estimatedRowHeight = 44.0 ;
self.table.rowHeight = UITableViewAutomaticDimension;

そしていま

-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;}
于 2015-05-19T14:21:40.403 に答える
10

ここでの回答の多くは、テーブルの変更を尊重していないか、あまりにも複雑です。UITableView自動レイアウトを使用する場合、適切に設定されるサブクラスを使用するintrinsicContentSize方がはるかに簡単なソリューションです。高さ制限などは必要ありません。

class UIDynamicTableView: UITableView
{
    override var intrinsicContentSize: CGSize {
        self.layoutIfNeeded()
        return CGSize(width: UIViewNoIntrinsicMetric, height: self.contentSize.height)
    }

    override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
    }
} 

インターフェイス ビルダーでTableView のクラスを に設定し、UIDynamicTableViewこの TableView が の呼び出し後にサイズを変更するので、魔法を観察しreloadData()ます。

于 2017-01-17T03:06:50.367 に答える
8

これは、viewDidAppear の 1 行のコードだけで大幅に簡素化できます。

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        tableViewHeightConstraint.constant = tableView.contentSize.height
    }
于 2016-05-11T15:54:44.153 に答える
5

ロブのソリューションは非常に優れていますが、彼の-(void)adjustHeightOfTableviewメソッドでの呼び出しは

[self.view needsUpdateConstraints]

何もせず、フラグを返すだけで、代わりに

[self.view setNeedsUpdateConstraints]

望ましい効果をもたらします。

于 2014-04-25T13:35:20.893 に答える
2

テーブルのサイズを変更するために、テーブルビューコントローラーの魔女でこのソリューションを使用しましたが、まったく問題ありません。

[objectManager getObjectsAtPath:self.searchURLString
                         parameters:nil
                            success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                NSArray* results = [mappingResult array];
                                self.eventArray = results;
                                NSLog(@"Events number at first: %i", [self.eventArray count]);
                                CGRect newFrame = self.activityFeedTableView.frame;
                                newFrame.size.height = self.cellsHeight + 30.0;
                                self.activityFeedTableView.frame = newFrame;

                                self.cellsHeight = 0.0;

                            }
                            failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                                message:[error localizedDescription]
                                                                               delegate:nil
                                                                      cancelButtonTitle:@"OK"
                                                                      otherButtonTitles:nil];
                                [alert show];
                                NSLog(@"Hit error: %@", error);
                            }];

リサイズ部分はメソッドになっていますが、見やすいように載せておきます。今私が持っている唯一の問題は、テーブルビューのサイズ変更がいつ終了したかわからないため、他のビューコントローラーでスクロールビューのサイズを変更することです。現時点では、私は performSelector: afterDelay: でそれをやっていますが、これは本当に良い方法ではありません。何か案は?

于 2013-01-14T13:02:25.120 に答える
2

シンプルで使いやすいコードを使用する

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let myCell = tableView.dequeueReusableCellWithIdentifier("mannaCustumCell") as! CustomCell
        let heightForCell = myCell.bounds.size.height;

        return heightForCell;
    }
于 2015-12-30T11:12:49.807 に答える