Несколько TableViews на одном экране - PullRequest
1 голос
/ 02 сентября 2011

У меня есть UIViewController, в котором я планирую разместить два TableViews и некоторые другие элементы. Оба TableViews я использую на других экранах, поэтому я хочу сделать их как можно более независимыми и повторно используемыми.Один из этих TableViews называется messageList (UITableView), который показывает мою ChatHistory.

Я пытаюсь понять, подходит ли мой подход.[Отредактировано 9/2 с правильным кодом, чтобы этот подход работал]

Один из подходов состоит в том, чтобы использовать одну таблицу с 2 различными разделами, а затем в методах делегатов использовать условный оператор, чтобы увидеть, какой раздел какой иДействуй соответственно.

Проблема этого подхода заключается в удобстве использования.Я хочу легко повторно использовать мои TableViews в других представлениях, где один или другой TableView может существовать или не существовать.Кроме того, я хочу, чтобы источник данных существовал на протяжении всего жизненного цикла приложения, независимо от того, какой контроллер создан или активен.

Мой подход заключается в том, чтобы отделить контроллер представления, который управляет представлениями таблицы, от реализаций таблицы UITableViewDataSource и UITableViewDelegate.Но у меня проблема с выполнением этой работы.

Сосредоточение внимания на одном из TableViews, моем ChatTableView.

В моем AppDelegate есть свойство для chatHistory типа ChatHistory, которое реализует UITableViewDelegate & UITableViewDataSource.

// AppDelegate.h

ChatHistory *chatHistory;
...
@property (nonatomic, retain) ChatHistory *chatHistory;

// ChatHistory.h

#import <Foundation/Foundation.h>

@interface ChatHistory : NSObject <UITableViewDelegate, UITableViewDataSource> {
    UITableViewCell *nibLoadedCell;
    NSMutableArray *messages;
}
@property (nonatomic, retain) UITableViewCell   *nibLoadedCell;
@property (nonatomic, retain) NSMutableArray    *messages;

@end

// ChatHistory.m - Обратите внимание, этот код, включая пользовательскую ячейку, работал правильно, когда она была частью контроллера, поэтому я считаю, что она должна быть правильной

#import "ChatHistory.h"
#include "ChatMessage.h"

@implementation ChatHistory
@synthesize nibLoadedCell;   // custom cell design
@synthesize messages;

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

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section {
return [messages count];
}

- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
return [NSString stringWithFormat:@"Discussion"];

}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"ChatTableCell" owner:self options:nil];
    cell = nibLoadedCell;
    }
    // custom tag order - username; message; future - Avatar; like; dislike
ChatMessage *obj = [messages objectAtIndex:indexPath.row];
UILabel *messageLabel = (UILabel *) [cell viewWithTag:1];
messageLabel.text = obj.message;
UILabel *usernameLabel = (UILabel *)[cell viewWithTag:2];
usernameLabel.text = obj.sender;
return cell;
}

- (void)dealloc {
    if (messages) [messages release];
    [super dealloc];
}
@end

//MyViewController.m

- (void)viewDidLoad {   // MAKE SURE TO INITIALIZE viewDidLoad not InitWithNib
        if (!appDelegate.chatHistory)
                appDelegate.chatHistory = [[ChatHistory alloc] init];

        messageList = [[UITableView alloc] initWithFrame:CGRectMake(0, 54, 320, 100) style:UITableViewStylePlain];
        messageList.dataSource = appDelegate.chatHistory;
        messageList.delegate = appDelegate.chatHistory;
        [self.view addSubview:messageList];
        ...

Ответы [ 3 ]

2 голосов
/ 02 сентября 2011

Вам не нужно делать контроллер представления вашим DataSource или делегатом для просмотра таблицы; любой объект может быть установлен. Вы можете использовать синглтон, как подсказывает Феликс, или любую другую структуру классов, какую пожелаете. Поскольку вы упоминаете, что хотите, чтобы история чата была доступна из любого места в приложении, имеет смысл предоставить протокол UITableViewDataSource для этой истории чата.

Что касается UITableViewDelegate, вы можете просто создать новый класс в качестве подкласса NSObject и реализовать там делегат. Убедитесь, что он создан и правильно сохранен, и установлен (при загрузке) в качестве делегата для ваших табличных представлений.

1 голос
/ 02 сентября 2011

Если вам нужно одно центральное хранилище данных, вы можете создать класс Singleton с данными.Затем установите его в качестве источника данных для табличного представления или извлеките массив (или все, что вы получили) из хранилища данных в вашем UIViewController / UITableViewController.

Если вы инициализируете хранилище данных в вашем AppDelegate, вы можете получить к нему доступ из любого класса, который вам нужен (обратите внимание, что все загружаемые вами данные будут оставаться в памяти до тех пор, пока ваше приложение не будет закрыто iOS)

Как создать класс Singleton в Objective-C

0 голосов
/ 02 сентября 2011

Я бы сделал это так: создайте два UITableView подпредставления одного контроллера представления.

В каждом из datasource методов, которые вы просто различаете между двумя таблицами, аналогично коду, который Apple предоставляет в примерах UISearchDisplayController. Например:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  if (tableView == myTableView1) {
    // return appropriate number of rows
  }
  // return appropriate number of rows for the other table view
}

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...