2013-05-01 2 views
3

Я пытаюсь поместить UITableView в UIView. UIView также будет содержать некоторые другие вещи, поэтому я хочу захотеть определить часть UIView, которая будет использоваться UITableView. Чтение на этом и других сайтах, я использую «UIViewController» и делегаты ».Как поместить UITableView в UIView

Мои вопросы:

  • Почему я не вижу UITable с ниже код?

  • Почему я вижу UITable, когда я меняю в InformatieSectieViewController.h

    @interface InformatieSectieViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> 
    

    в

    @interface InformatieSectieViewController : UIViewTableController <UITableViewDataSource, UITableViewDelegate> 
    

    (UIViewController до УИ Таблица ViewController)? (Этот UITable затем обрабатывает весь UIView).

  • Как правильно получить UITableView в UIView.

  • Что меня также удивляет; когда я удалить < UITableViewDataSource, UITableViewDelegate> часть из @interface InformatieSectieViewController: UIViewController < 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 

InformatieSectie.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 :

В formatieSectieViewController.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 
+0

Кстати, это очень интересно посмотреть, 'InformatieSectie' быть' NSObject' подкласс. Если задача заключается в создании объекта 'UIView', гораздо более распространенным является то, что он фактически является подклассом UIView. См. [Создание пользовательского представления] (http://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW23). в Руководстве по программированию _View. Или существует ли какое-то другое соображение, которое не было разделено с нами? – Rob

ответ

6

Несколько наблюдений:

  1. Вы спросили:

    Когда я удалить <UITableViewDataSource, UITableViewDelegate> часть из

    @interface InformatieSectieViewController : UIViewController < UITableViewDataSource, UITableViewDelegate> 
    

    Я ожидаю предупреждения на линиях (в InformatieSectieViewController.м):

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

    Но я не получаю это предупреждение.

    Да, это любопытно. Если вы используете UIViewController, вы действительно должны увидеть эти предупреждения. Если у вас есть другие предупреждения, иногда вы не увидите никаких последующих предупреждений. Или иногда, если вы редактируете заголовок, не сохраняйте и/или не создавайте, вы можете не видеть предупреждение до тех пор, пока не сделаете это. Или попробуйте выбрать «Очистить» в меню «Построить», а затем перестроить и посмотреть, получилось ли предупреждение.

    Независимо от того, даже если вы не видите эти предупреждения, вы все равно должны определить его для соответствия этим двум протоколам, поскольку это упростит выполнение кода в Xcode.

    Если вы используете UITableViewController в качестве базового класса, вам не нужно определять его как соответствующий этим двум протоколам, поскольку он уже соответствует UITableViewDataSource и UITableViewDelegate.

  2. Как добавить TableView, как подвид

    И в ответ на широкий вопрос о том, как добавить представление таблицы на вид с другим материалом на ней, а не делать следующее loadView:

    self.view = tabview; 
    

    вы должны вместо этого делать следующее loadView:

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

    Или, если вы не строить вид про грамматический в loadView, а с помощью СИБА или раскадровки, вы можете просто сделать следующее viewDidLoad:

    [self.view addSubview:tabview]; 
    

    Несмотря на это, убедившись, у вас есть еще один главный UIView, и ваш UITableView являются подтаблицами, вы можете поэтому добавьте другие элементы управления к этому основному виду.

  3. и вид иерархий контроллер

    Заглядывая в свой образец кода, я вижу, что вы создаете контроллер, схватив свою точку зрения, добавив, что вид как подвид, а затем позволить падение контроллера из объем. Это очень плохая практика. Если ARC, вы получите исключения. Если не-ARC, вы будете утечка, если вы когда-нибудь отклоните это представление (но не проблема, если это ваш вид верхнего уровня).

    Хуже того, если вы это сделаете, контроллер вашего вида не получит определенных событий (в частности, событий ротации, но, возможно, других). См. WWDC 2011 - Implementing UIViewController Containment для обсуждения важности синхронизации вашего представления и просмотра иерархии контроллеров.

    Если это ваш контроллер верхнего уровня, вы должны установить этот контроллер как 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; 
    } 
    

    Если этот вид контроллер не контроллер верхнего уровня, вы можете создать его в контроллере предлежащего, и либо сделать модальную или толкать SEGUE от контроллера представления предлежащего, например,:

    - (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]; 
    } 
    

    Любой один из этих трех методов будет гарантировать, что ваш взгляд иерархия контроллера будет синхронизирована с вашей иерархией представлений. Я знаю, что это похоже на то, что это слишком много, но позже вы столкнетесь с проблемами, если не справитесь с этим одним из этих трех способов.

Я знаю, что здесь много, но я надеюсь, что это поможет. Прошу прощения, если это сбивает с толку.

+0

Спасибо за ваш ответ. Я понимаю, что UITableViewController соответствует UITableViewDataSource и UITableViewDelegate. Я имел в виду, что я ожидаю предупреждения, когда я использую UIViewController вместо UITableViewController. –

+0

@PeterVerwoerd re предупреждения для 'delegate' и' dataSource', я вас неправильно понял (поскольку я видел, что вы определяете свой 'UITableViewController' как соответствующий этим двум протоколам, что необязательно, потому что оно уже соответствует) и обнаруживают, что, когда вы определили' UIViewController', который не соответствовал тому, что вы не получили предупреждений. Я получаю предупреждения. Иногда, если в начале кода есть предупреждения, последующие не генерируются. Не уверен. В нижней строке, при использовании 'UIViewController', вы должны объявить его совместимым с этими двумя протоколами, но при использовании' UITableViewController' вам не следует. – Rob

+0

Thanx, вот что я и подумал. Не знаю, почему я не получаю предупреждений, хотя я еще раз посмотрю на это. –

0

Вы должны сделать [self.view addSubview:self.tabView] вместо self.view = self.tabView

+0

Когда я меняю 'self.view = tabview;' на @Rob '[self.view addSubview: tabview];' или @karlofk '[self.view addSubview: self.tabView]', есть своего рода рекурсивное вызов и Я в итоге с 65000 stacktraces: - | –

+0

@PeterVerwoerd см. Мой пересмотренный ответ. 'loadView' должен сделать основной вид, а затем добавить представление таблицы как subview (если вы не хотите, чтобы таблица занимала весь экран). – Rob

+1

ОК, с предложением @Rob 'self.view = [[UIView alloc] init]; 'Рекурсивное призвание ушло. Thanx :-) –

Смежные вопросы