Как передать данные в подробный вид после выбора в виде таблицы? - PullRequest
4 голосов
/ 27 сентября 2011

У меня есть UITableViewController, в котором есть данные, заполненные из NSMutableArray с именем userList.Когда выбран конкретный пользователь, он переходит в подробный вид и обновляет заголовок в NavBar, но не передает данные для обновления UILabel в UIView.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[tableView deselectRowAtIndexPath:indexPath animated:NO];

//Attempt at a singleton to pass the data
DetailView *details = [[DetailView alloc] init];
details.userNameLbl = [userList objectAtIndex:indexPath.row];


DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];

//This line doesn't pass the data
detailVC.userNameLbl.text = [userList objectAtIndex:indexPath.row];

//This line does update the title in the NavBar
detailVC.navigationItem.title = [userList objectAtIndex:indexPath.row];

[self.navigationController pushViewController:detailVC animated:YES];

[details release];
[detailVC release];

}

Стоит ли пытаться перенести данные из табличного представления в подробное представление, или же подробное представление пытается извлечь данные из табличного представления?

DetailView.hимеет следующую строку, которая фактически подключена в IB.

IBOutlet UILabel *userNameLbl

Ответы [ 3 ]

11 голосов
/ 27 сентября 2011

userNamelbl не создается, пока представление не будет загружено из файла пера. Это не происходит сразу при инициализации, но произойдет ко времени вызова viewDidLoad.

Итак, вам нужно объявить свойство в DetailView для хранения вашего заголовка, а затем присвоить это значение userNamelbl.text в методе viewDidLoad.

Например, в вашей таблице viewController:

DetailView *detailVC = [[DetailView alloc] initWithNibName:nil bundle:nil];
detailVC.userName = [userList objectAtIndex: indexPath.row];

и в ваших подробностях viewController:

- (void) viewDidLoad
{
   [super viewDidLoad];
   self.userNameLbl.text = self.userName;
}

Свойство viewIontroller navigationItem создается при инициализации viewController, поэтому вы можете немедленно присвоить navigationItem.title.


Код Swift

let detailVC = DetailView(nibName: nil, bundle: nil)
detailVC.userName = userList.objectAtIndex(indexPath.row) as? NSString

и

class DetailView: UIViewController {

    @IBOutlet var userNameLbl: UILabel
    var userName:NSString?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.userNameLbl.text = self.userName
    }    
} 
4 голосов
/ 27 сентября 2011

Вы смешиваете UIViews и UIViewControllers? У вас должен быть класс DetailViewController, который наследуется от UIViewController или некоторого подкласса (например, UITableViewController); в нем будут DetailViewController.m и DetailViewController.h файлы для объявления и определения вашего класса. Он должен иметь соответствующий кончик, который определяет UIView, который загружает UIViewController; он будет иметь DetailView.xib файл.

Вы не можете присвоить значение UILabel напрямую, потому что UIView не был загружен в то время, когда вам нужно присвоить значение имени пользователя.

Для того, чтобы делать то, что вы хотите, вы должны объявить открытое свойство (userName), чтобы «выдвинуть» значение в контроллер подробного представления из главного контроллера. После того, как подробный вид загружен, он может присвоить значение из свойства метке и навигационной панели.

В вашем главном контроллере представления (UITableViewController):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    DetailViewController *detailVC = [[DetailView alloc] initWithNibName:@"DetailView" bundle:nil];

    detailVC.userName = [userList objectAtIndex:indexPath.row];

    [self.navigationController pushViewController:detailVC animated:YES];

    [detailVC release];
}

В вашем детализированном виде контроллер:

DetailViewController.h

@property (retain) NSString* userName;
@property (nonatomic, retain) IBOutlet UILabel *userNameLbl;

DetailViewController.m

@synthesize userName;
@synthesize userNameLbl;

-(void) viewDidLoad {
    [super viewDidLoad];
    self.userNameLbl.text = self.userName;
    self.navigationItem.title = self.userName;
}
0 голосов
/ 27 сентября 2011

Предположительно, вашему DetailView требуются данные из выбранной строки для работы?

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

[[DetailView alloc] initWithTitle:(NSString *)title text:(NSString *)text]

В вашем подходе нет ничего неправильного, но передача данных, необходимых контроллеру представления при его создании, архитектурно лучше (на мой взгляд, я уверен, что кто-то не согласится!).Например, подумайте о контроллере табличного представления - вы передаете стиль табличного представления в методе init, но не устанавливаете его позже.То же самое для UIImageView - у вас есть метод initWithImage, который позволяет вам устанавливать изображение при создании.

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