4

UITableView を UIView に入れようとしています。UIView には他にもいくつかの要素が含まれるため、UITableView で使用される UIView の一部を定義したいと考えています。このサイトや他のサイトを読んで、「UIViewController」とデリゲート「」を使用しています。

私の質問は次のとおりです。

  • 以下のコードで UITable が表示されないのはなぜですか?

  • InformatieSectieViewController.h を変更すると UITable が表示されるのはなぜですか

    @interface InformatieSectieViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
    

    @interface InformatieSectieViewController : UIViewTableController <UITableViewDataSource, UITableViewDelegate>
    

    (UIViewController から UIテーブルViewController)? (この UITable は UIView 全体を占有します)。

  • UITableView を UIView に正しく取得するにはどうすればよいですか。

  • また、私を驚かせたこと。@interface InformatieSectieViewController : UIViewController < UITableViewDataSource, UITableViewDelegate> から < UITableViewDataSource, UITableViewDelegate> 部分を削除すると、(InformatieSectieViewController.m 内の) 行に警告が表示されます。

    tabView.delegate = self;
    tabView.dataSource = self;
    

    しかし、私はこの警告を受けません。

私が使用しているコードは次のとおりです。

InformatieSectie.h

#import <UIKit/UIKit.h>
@interface InformatieSectie : NSObject
@property (strong, nonatomic) NSString *header;
-(UIView*)createInformatieSectie;
@end

情報Sectie.m

#import "InformatieSectie.h"
#import "InformatieSectieViewController.h"
#import <QuartzCore/QuartzCore.h>
@implementation InformatieSectie
@synthesize header;
@synthesize footer;
-(UIView*)createInformatieSectie{
    UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 200, breedte, hoogte)];
    //(add headerlabel at pos)
    [view addSubview:headerLabel];

    InformatieSectieViewController *svc = [[InformatieSectieViewController alloc] init];

    [view addSubview:svc.view];
    return view;
}
@end

これは、UITableView を定義する 2 番目のクラスです。

InformatieSectieViewController.h

#import <Foundation/Foundation.h>
@interface InformatieSectieViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, retain) UITableView *tabView;
@end

InformatieSectieViewController.m

#import "InformatieSectieViewController.h"
#import <QuartzCore/QuartzCore.h>
@implementation InformatieSectieViewController
@synthesize tabView;

-(void)loadView {
    tabView = [[UITableView alloc] initWithFrame:CGRectMake(100, 100, 20, 20)];
    tabView.delegate = self;
    tabView.dataSource = self;
    tabView.layer.borderWidth = 10.0;
    tabView.layer.borderColor = [UIColor yellowColor].CGColor;
    self.view = tabView;
    self.view.layer.backgroundColor = [UIColor magentaColor].CGColor;
    [super loadView];     
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}        

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // (return some cell)
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // (Nothing yet)
}
@end
4

2 に答える 2

6

いくつかの観察:

  1. あなたは尋ねました:

    <UITableViewDataSource, UITableViewDelegate>パーツを外すと

        @interface InformatieSectieViewController : UIViewController < UITableViewDataSource, UITableViewDelegate>
    

    (InformatieSectieViewController.m 内の) 次の行に警告が表示されると思います。

        tabView.delegate = self;
        tabView.dataSource = self;
    

    しかし、私はこの警告を受けません。

    はい、それは興味深いです。を使用するUIViewControllerと、これらの警告が実際に表示されるはずです。他の警告がある場合、その後の警告が表示されないことがあります。または、ヘッダーを編集して保存および/またはビルドしない場合、実行するまで警告が表示されないことがあります。または、[ビルド] メニューから [クリーン] を選択して再ビルドし、警告が表示されるかどうかを確認してください。

    とにかく、これらの警告が表示されなくても、Xcode でのコード補完が容易になるため、これら 2 つのプロトコルに準拠するように定義する必要があります。

    ただし、 を基本クラスとして使用する場合は、およびUITableViewControllerに既に準拠しているため、これら 2 つのプロトコルに準拠していると定義する必要はありません。UITableViewDataSourceUITableViewDelegate

  2. テーブルビューをサブビューとして追加する方法

    で次のことを行うのではなく、他のものを含むビューにテーブルビューを追加する方法に関するより広範な質問への回答loadView:

    self.view = tabview;
    

    代わりに、 で次のことを行う必要がありますloadView

    self.view = [[UIView alloc] init];
    [self.view addSubview:tabview];
    

    または、 でプログラムによってビューloadViewを作成するのではなく、NIB またはストーリーボードを使用する場合は、 で次の操作を実行できますviewDidLoad

    [self.view addSubview:tabview];
    

    いずれにせよ、別のメイン ビューとサブビューがあることを確認することUIViewUITableView、そのメイン ビューに他のコントロールを追加できます。

  3. コントローラー階層の表示と表示

    コード サンプルをさらに調べると、コントローラーを作成し、そのビューを取得し、そのビューをサブビューとして追加してから、コントローラーを範囲外にしていることがわかります。それは本当に悪い習慣です。ARC の場合、例外が発生します。非 ARC の場合、このビューを閉じるとリークが発生します (ただし、これが最上位のビューである場合は問題ありません)。

    さらに悪いことに、これを行うと、View Controller が特定のイベントを受信しなくなります (特に回転イベントですが、他のイベントも発生する可能性があります)。ビューとビュー コントローラー階層の同期を維持することの重要性については、WWDC 2011 - UIViewController コンテインメントの実装を参照してください。

    これが最上位のコントローラーである場合、このコントローラーを に設定する必要がありrootViewControllerます。たとえば、アプリのデリゲートで次のようにします。

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
        // Override point for customization after application launch.
    
        // create your controller any way you want
    
        self.viewController = [[InformatieSectieViewController alloc] init];
    
        // if not using ARC, it should be
        //
        // self.viewController = [[[InformatieSectieViewController alloc] init] autorelease];
    
        // by defining this as your root view controller, you'll be assured that the controller
        // is now part of the controller hierarchy
    
        self.window.rootViewController = self.viewController;
    
        [self.window makeKeyAndVisible];
    
        return YES;
    }
    

    このビュー コントローラーが最上位のコントローラーでない場合は、表示するコントローラーで作成し、モーダルを実行するか、表示するビュー コントローラーからセグエをプッシュします。次に例を示します。

    - (void)transitionToNextViewController
    {
        UIViewController *controller = [[InformatieSectieViewController alloc] init];
    
        // again, if not using ARC, that line should be:
        //
        // UIViewController *controller = [[[InformatieSectieViewController alloc] init] autorelease];
    
        [self presentViewController:controller animated:YES completion:nil];
    
        // or
        // [self.navigationController pushViewController:controller animated:YES];
    }
    

    または、まれにカスタム コンテナー ビュー コントローラーを使用している場合は、次のようにします。

    - (void)addChild
    {
        UIViewController *controller = [[InformatieSectieViewController alloc] init];
    
        // again, if not using ARC, that line should be:
        //
        // UIViewController *controller = [[[InformatieSectieViewController alloc] init] autorelease];
    
        [self addChildViewController:controller];
        controller.view.frame = CGRectMake(x, y, width, height);
        [self.view addSubview:controller.view];
        [controller didMoveToParentViewController:self];
    }
    

    これら 3 つの手法のいずれかを使用すると、ビュー コントローラーの階層がビューの階層と確実に同期されます。これはやり過ぎのように思えますが、これら 3 つの方法のいずれかで処理しないと、後で問題が発生します。

ここにたくさんあることは知っていますが、役に立てば幸いです。紛らわしい場合は申し訳ありません。

于 2013-05-01T13:35:27.247 に答える