2013-06-14 16 views
5

Xcode 4.6.1 iOS 6 wykorzystujące storyboardymożliwe jest segue z UITableViewCell na UIView do innego widoku

Mój problem polega na tym

Mam UITableView z dynamicznych komórek prototypowych na UIView w miłym UIViewController (który sam jest wbudowane w kontroler nawigacji) i chcę segue od jednej konkretnej komórki do innego widoku

(Zanim ktoś sugeruje, należy po prostu być przy użyciu UITableViewController, mam inne rzeczy na UIView, tak ja w ten sposób skonfigurowany w ten sposób.)

Teraz nie wiem, jak utworzyć segment

Jeśli przeciągnę z prototypu UITableViewCell, aby utworzyć przejście, wszystkie wygenerowane komórki automatycznie wywołają segue - kiedy potrzebuję tylko jednego, aby to zrobić. Jest to normalne zachowanie i obejdę to, gdybym używał UITableViewController, tworząc przejście, przeciągając od UITableViewController i wywołując [self performSegueWithIdentifier: .... Z mojego didSelectRowAtIndexPathMethod tak, że tylko określona komórka, którą chcę wykonać, przełącza go .

ja nie mam UITableViewController w tym przypadku - tylko mój UITableView na UIView, który jest częścią UIViewController podklasy

Grałem wokół i właśnie odkrył, że nie można przeciągać z UITableView - nie pozwala ci tego zrobić, więc to był deadend.

Moim jedynym wyborem, który wydawał mi się w lewo, aby przeciągnąć z UIViewController

więc próbowałem to i oczywiście XCode rzuca się na błąd wykonania linii Segue mówią mi, że mam ... nie widzialnym interfejs "LocationTV" deklaruje selektor performSegueWithIdentifier. LocationTv jest moją podklasą widoku tabeli.

Co to jest poprawny sposób próbować wywołać nowy widok w tej sytuacji

podziÄ ™ kowaniami

Simon

Odpowiedz

3

moje rozwiązanie

skończyło się stosując wzór delegacji

Zrobiłem segue przeciąganie z moim UIViewController - specjalnie przeciąganie z ikoną viewController (pomarańczowe kółko z białym kwadratem w nim - z paska nazw widocznego pod widokiem w serii ujęć - chociaż można też przeciągnąć z paska bocznego) do widoku, który chciałem przenieść.

Musiałem wyzwolić tę zmianę z komórki widoku tabeli w widoku tabeli.

Tableview Bit

Więc ogłoszony protokół w moim pliku nagłówka tableview - który nazywa LocationTV.h - następująco

@protocol LocationTVSegueProtocol <NSObject> 

-(void) makeItSegue:(id)sender; 

@end 

poniżej tej zadeklarować właściwość trzymać delegata

@property (nonatomic, strong) id<LocationTVSegueProtocol> makeSegueDelegate; 

Aby w rzeczywistości wywołać sesję o nazwie makeItSegueMethod w moim makeSequeDelegate w moim didSelectRowAtInd Metoda exPath

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

switch (indexPath.section) { 
     DLog(@"selected row %d",indexPath.row); 
    case dLocation: 
    { 
     if(indexPath.row == 2){ 

      [_makeSegueDelegate makeItSegue:self]; 

     } else if (indexPath.row == 7){ 

UIViewController Bit

i skonfigurować UIViewController (nazwany MultiTableHoldingVC) jako wdrożenie tego protokołu

@interface MultiTableHoldingView : UIViewController  
            <EnviroTVProtocol,LocationTVSegueProtocol> { 

} 

Poniżej że zadeklarowane metody protokołu na liście moich zajęciach metody (chociaż nie jestem pewien, czy jest to konieczne, ponieważ kompilator powinien wiedzieć o metodzie, ponieważ dekalracja implementacji protokołu jest w gruncie rzeczy obietnicą wdrożenia tej metody)

-(void) makeItSegue:(id)sender; 

A potem w ciągu w pliku implementacji moim UIViewController napisałem metodę, która w istocie po prostu wywołuje preformSegueWithIdentifier

-(void) makeItSegue:(id)sender{ 
    [self performSegueWithIdentifier:@"ChooseCountryNow" 
           sender:sender]; 
} 

oraz powiązanie to wszystko razem, jak w pliku nagłówka I zadeklarowały moje wystąpienie z tableview następująco

@property (strong, nonatomic) IBOutlet LocationTV *dsLocationTV; 

musiałem ustawić tę właściwość widoki tabel delegata na własny - co zrobiłem w moich UIViewControllers - (void) viewDidLoad metoda

_dsLocationTV.makeSegueDelegate = self; 

to wszystko wydaje się trochę kludge wywołanie metody do wywołania metody i ALLPROG propozycja jest prostsza (nie mogę dla życia mnie pracować się, dlaczego rzucił się błędy dla mnie), ale to działa dobrze . Dzięki zarówno allprog, jak i danemu za sugestie.

Nadzieja jest to pomocne, aby ktoś tam

0

performSegueWithIdentifier: to metoda klasy UIViewController. Nie można wywołać go w instancji UITableView. Ustaw kontroler widoku zaimplementuj protokół UITableViewDelegate i ustaw go jako delegata dla UITableView.

Inną opcją jest to, że nie używasz segues.W tej samej metody delegata zrobić:

OtherViewController ov = [[OtherViewController alloc] init<<some initializer>>]; 
// Or in case of storyboard: 
OtherViewController ov = [self.storyboard instantiateViewControllerWithIdentifier:@"ovidentifier"]; 

// push view controller 
[self.navigationController pushViewController:ov animated:YES]; 

Jeśli obiekt delegat różni się od kontrolera widoku, a następnie Najprostszym rozwiązaniem jest dodanie słaby właściwość klasy delegata, że ​​utrzymuje odniesienie do viewController, jak to:

@property (weak) UIViewController *viewController; 

i ustawić go w viewDidLoad z viewController

- (void) viewDidLoad { 
    self.tableView1.viewController = self; 
} 

Upewnij się, że nieruchomość tableView1 jest zadeklarowana następująco:

@property (IBACTION) (weak) SpecialTableView *tableView1; 

Czasami pomocą storyboard jest bardziej bolesne niż pisanie kodu samodzielnie.

+0

Moja tableview jest już własny UITableViewDelegate. (Mam 4 różne odsłony tabel, które użyłem UISegmentedCntrol do przełączania ukrytych właściwości włączania i wyłączania, więc tylko jeden pojawia się na raz - jeden z tych widoków tabel, które muszą wywoływać nowy widok). Czy to oznacza niepotrzebną potrzebę przeniesienia wszystkich rzeczy delegowanych z UITableView na UIViewController, na którym siedział? – SimonTheDiver

+0

Utworzono więc specjalistyczne klasy UITableView. Klasy te muszą mieć sposób na uzyskanie dostępu do kontrolera ViewController, w którym działają, lub musisz utworzyć implementację podobną do tej, którą proponuje inna odpowiedź. Poszukałbym prostoty i stworzenia właściwości (nazwij ją 'viewController') w podklasach UITableview zawierających odniesienie do ViewController. W 'didSelectRowAtIndexPath:' możesz wywołać '[self.viewController performSegueWithIdentifier: identyfikator]'. Właściwość 'viewController' powinna być ustawiona w' viewDidLoad' kontrolera widoku. – allprog

+0

Zdefiniowałem protokół (z metodą do wywołania performSegue) wewnątrz mytableView.h i sprawił, że moja podklasa UIViewContoller jest zgodna z tym. Podobny do danypata suggested.Worked. Twój pomysł wydaje się być prostszy i chcę go wypróbować. Zaimportowałem klasę UIViewController - #import "MultiTableHoldingView.h" do mojej podklasy UItableView, ale gdy próbowałem ją zadeklarować w interfejsie mojej podklasy tableView- @property (nonatomic, strong) MultiTableHoldingView * theParentViewController; Błędy -i get2: Właściwość z atrybutem zatrzymania (lub silnym) musi być wyłączona typ obiektu i nieznana nazwa typu "Widok tabeli MultiTableHolding". pomysły? – SimonTheDiver

5

Przede wszystkim segues może być używany tylko między UIViewControllers. Jeśli więc chcesz wykonać przejście między dwoma widokami, które znajdują się na tym samym sterowniku widoku, to jest niemożliwe.

Ale jeśli chcesz wykonać przejście między dwoma kontrolerami widoku, a segue powinno być wyzwalane przez akcję z jednego widoku (wewnątrz kontrolera pierwszego widoku), to jest to możliwe.

W twoim przypadku, jeśli rozumiem pytanie, chcesz przeprowadzić segue, gdy zostanie naciśnięta pierwsza komórka z UITableView, która jest wewnątrz niestandardowego UIView. Najprostszym rozwiązaniem byłoby stworzenie delegata na swoim zwyczajem UIView które będą realizowane przez UIViewController, który zawiera niestandardowe UIView gdy metoda delegat nazywa należy wykonać segue, Oto krótki przykład:

YourCustomView. H

@protocol YourCustomViewDelegate <NSObject> 

-(void)pleasePerformSegueRightNow; 

@end 

@interface YourCustomView : UIView { 
    UITableView *theTableView; //Maybe this is a IBOutlet 
} 
@property(weak, nonatomic) id<YourCustomViewDelegate>delegate; 

YourCustomview.m

@implementation YourCustomview 
@ synthesise delegate; 

//make sure that your table view delegate/data source are set properly 
//other methods here maybe 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    if(indexPath.row == 0) { //or any other row if you want 
     if([self.delegate respondsToSelector:@selector(pleasePerformSegueRightNow)]) { 
      [self.delegate pleasePerformSegueRightNow]; 
     } 
    } 
} 

YourTableViewController.h

@interface YourTableViewController : UIViewController <YourCustomViewDelegate> { 
    //instance variables, outlets and other stuff here 
} 

YourTableViewController.m

@implementation YourTableViewController 

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    YourCustomView *customView = alloc init.... 
    customView.delegate = self; 
} 

-(void)pleasePerformSegue { 
    [self performSegueWithIdentifier:@"YourSegueIdentifier"]; 
} 

Można tworzyć jakiekolwiek metody do delegata lub można dostosować zachowanie, jest to tylko prosty przykład, jak można Zrób to.

+0

Hi danypata - udało mi się uzyskać działający fragment kodu, definiując protokół w mojej podklasie UITableView i sprawiają, że UIViewController jest zgodny z protokołem i przy użyciu metody podobnej do twojej sugerowanej pleasePerformSegueto zadzwoń do metody performSegue na I did not mylić przez twoją odpowiedź, ponieważ nie podklasy UIView na UIViewController ale dostałem się tam w końcu tak okrzyki dla tego – SimonTheDiver

+0

@SimonTheDiver, jeśli jedna z dwóch odpowiedzi zamieszczonych na twoje pytanie, jest właściwa, proszę oznaczyć ją jako zaakceptowaną, lub jeśli masz lepszą, opublikuj ją i oznacz jako zaakceptowaną;) – danypata

+0

Nie martw się - będę - I Próbuję tylko sprawdzić, czy mogę zasugerować wszystkie sugestie, zanim zacznę o nich pisać, lub zrobię sobie kodowany przykład. – SimonTheDiver

Powiązane problemy