DidSelectRowAtIndexPath veya UITableView için hazırlaForSegue yöntemini mi kullanın?


101

Film şeridi kullanıyorum ve bir UITableView'ım var. Masamdan ayrıntı VC'ye iten bir segment kurulumum var. Ama bununla başa çıkmak için hangi yöntemi kullanmalıyım? Detay görünümüne birkaç nesne geçirmem gerekecek. Ama kullanabilirim didSelectRowAtIndexveya -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender?

Yanıtlar:


199

Eğer kullanırsanız prepareForSegue:sender:o zaman sonradan tablo görünümü dışında bazı kontrolünden segue tetiklemek için karar verirseniz değişikliğine kadar olmaz.

prepareForSegue:sender:Böyle bir şey öneririm böylece mesajı, geçerli görünüm kontrolöre gönderilir:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Assume self.view is the table view
    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    DetailObject *detail = [self detailForIndexPath:path];
    [segue.destinationViewController setDetail:detail];
}

Swift'de:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let path = self.tableView.indexPathForSelectedRow()!
    segue.destinationViewController.detail = self.detailForIndexPath(path)
}

1
Tamam, indexPath'e dayalı bir nesne geçirerek nasıl uygulanacağına dair bir örnek verebilir misiniz?
Jon

4
self.viewsadece senderburada olmamalı mı? [self.view indexPathForSelectedRow]İşe bile gidemedim , yapmak zorundaydım[sender indexPathForSelectedRow];
ladookie

Bunu Swift'de nasıl yaparsınız?
Kullanıcı

@robmayoff Bunu Swift için güncellediğiniz için teşekkürler. Son dil değişikliklerini yansıtmak için bazı küçük düzenlemeler yaptım. Umarım bu başkalarına yardımcı olur
Zack Shapiro

Çağrıldığında tableView.indexPathForSelectedRow()doğru değeri içermesi tuhaftır prepareFroSegue...: tableView(_:didSelectrowAtIndexPath:)daha sonrasına kadar çağrılmaz.
Nicolas Miari

5

Bunu yaptım ve işe yaradı

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

    NSLog(@"Row Selected = %i",indexPath.row);

    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}

11
Bu mantıklı değil. Ya segmenti VEYA tablo görünümü temsilcisini kullanmalısınız. Sadece Hücreden bir segment oluşturun ve kod yazmadan yaptığınız aynı şeyi otomatik olarak gerçekleştirecektir.
Yariv Nissim

3
didSelectRow olmadan bir hücreye nasıl segment atarsınız?
Morkrom

3

Gönderen UITableViewCell olduğunda, UITableView'dan hücrenin indexPath'ini sorgulamasını isteyebilirsiniz.

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let cell = sender as? UITableViewCell {
            let indexPath = self.tableView.indexPathForCell(cell)!
            assert(segue.destinationViewController.isKindOfClass(DetailViewController))
            let detailViewController = segue.destinationViewController as! DetailViewController
            detailViewController.item = self.items[indexPath.row] // like this
        }
    }

1

tableView mülkünüz başka bir sınıftaysa ve yalnızca bir bölümünüz varsa tag, hücrenin satırını şu şekilde depolamak için özelliği kullanabilirsiniz :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

     cell.tag = indexPath.row;

     return cell;
}

Ve sonra sender, etiketindeki satır değeriyle aynı hücre olduğu için ona erişebilirsiniz :

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    MyDestinationViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
}

1

self.tableView.indexPathForSelectedRowseçili hücreyi döndürür, ancak gönderen hücresini segmente etmez, örneğin, gönderen hücresi seçilmemiştir (yardımcı eylem) veya çoklu seçim durumunda. En iyi yol, segment gönderen için indexPath almaktır:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    __auto_type itemViewController = (id<ItemViewController>)segue.destinationViewController;
    itemViewController.senderIndexPath = [self.tableView indexPathForCell:sender];
}

Swift'de:

protocol ItemViewController {
    var senderIndexPath : IndexPath? { get set }
    var selectedIndexPaths : [IndexPath]? { get set }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if  let cell = sender as? UITableViewCell,
        var itemViewController = segue.destination as? ItemViewController {
        itemViewController.senderIndexPath = tableView.indexPath(for: cell)
        itemViewController.selectedIndexPaths = tableView.indexPathsForSelectedRows
    }
}

0

Eğer kullanıyorsanız prepareForSegue:, gönderenin kim olduğunu kontrol edebilir ve farklı kod çalıştırabilirsiniz.

Örneğin hızlı

override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
{
   var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)

   if senderIsTableviewCell
   {
       //do something
   }
}

2
Yapmanız gereken: eğer tableViewCell = gönderen? UITableViewCell {// bir şeyler yapın} . Gönderen bir UITableViewCell'e dönüştürülemezse, "bir şeyler yap" yürütülmez.
mbeaty
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.