2012-12-05 13 views
5

Jestem dość nowy w programowaniu iOS i mam problem, którego sam nie byłem w stanie rozwiązać.UITableViewCell dowiązanie do konkretnej strony w PageViewController

Główną częścią mojej aplikacji jest lista zwierząt (AnimalTableViewController), którą można wyszukać (ta funkcja działa). Po kliknięciu na wybraną komórkę powinno być możliwe wyświetlenie obrazu zwierzęcia. Wszystkie obrazy zwierząt są kompilowane w PagerViewController (CustomPagerViewController).

image of my storyboards can be found here http://i50.tinypic.com/ve14r4.jpg

Co muszę zrobić, to połączyć dynamiczną komórkę tabeli do konkretnego widoku/ujęć. Mogłem wcześniej połączyć komórkę z obrazem - tablica obrazów była wyświetlana w jednym kontrolerze widoku. Zdecydowałem się zrobić to za pomocą PagerViewController tym razem, ponieważ potrzebowałem funkcji Swipe (metody związane z machnięcia można znaleźć w PagerViewController.m i wszystkie działają zgodnie z oczekiwaniami).

Proszę, pomóż mi z tym, nie znalazłem żadnego tutoriala ani porady, jak przekazywać dane między UITableView i PagerViewController.

AnimalTableViewController.m

@implementation AnimalTableViewController 

@synthesize allTableData; 
@synthesize filteredTableData; 
@synthesize searchBar; 
@synthesize isFiltered; 
@synthesize tableView; 

- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super init]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)didReceiveMemoryWarning 
{ 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 
} 

#pragma mark - View lifecycle 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    tableView.delegate = (id)self; 
    tableView.dataSource = (id)self; 

    searchBar.delegate = (id)self; 

    allTableData = [[NSMutableArray alloc] initWithObjects: 
        [[Animal alloc] initWithName:@"Aardvark" andDescription:@"Aardvark"], 
        [[Animal alloc] initWithName:@"Alligator" andDescription:@"Alligator"], 
        [[Animal alloc] initWithName:@"Alpaca" andDescription:@"Alpaca"], 
        [[Animal alloc] initWithName:@"Ant" andDescription:@"Ant"], 
        [[Animal alloc] initWithName:@"Anteater" andDescription:@"Anteater"], 
        [[Animal alloc] initWithName:@"Armadillo" andDescription:@"Armadillo"], 
        [[Animal alloc] initWithName:@"Baboon" andDescription:@"Baboon"], 
        [[Animal alloc] initWithName:@"Badger" andDescription:@"Badger"], 
        [[Animal alloc] initWithName:@"Bat" andDescription:@"Bat"], 
        [[Animal alloc] initWithName:@"Bear" andDescription:@"Bear"], 
        [[Animal alloc] initWithName:@"Beaver" andDescription:@"Beaver"], 
        [[Animal alloc] initWithName:@"Bee" andDescription:@"Bee"], 
        [[Animal alloc] initWithName:@"Bison" andDescription:@"Bison"], 
        nil ]; 
} 

- (void)viewDidUnload 
{ 
    [self setSearchBar:nil]; 
    [super viewDidUnload]; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

#pragma mark - Table view data source 

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    int rowCount; 
    if(self.isFiltered) 
     rowCount = filteredTableData.count; 
    else 
     rowCount = allTableData.count; 

    return rowCount; 
} 

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

    Animal* animal; 
    if(isFiltered) 
     animal = [filteredTableData objectAtIndex:indexPath.row]; 
    else 
     animal = [allTableData objectAtIndex:indexPath.row]; 

    cell.textLabel.text = animal.name; 
// cell.detailTextLabel.text = animal.description; 

    return cell; 
} 

#pragma mark - Table view delegate 

-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text 
{ 
    if(text.length == 0) 
    { 
     isFiltered = FALSE; 
    } 
    else 
    { 
     isFiltered = true; 
     filteredTableData = [[NSMutableArray alloc] init]; 

     for (Animal* animal in allTableData) 
     { 
      NSRange nameRange = [animal.name rangeOfString:text options:NSCaseInsensitiveSearch]; 
      NSRange descriptionRange = [animal.description rangeOfString:text options:NSCaseInsensitiveSearch]; 
      if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound) 
      { 
       [filteredTableData addObject:animal]; 
      } 
     } 
    } 

    [self.tableView reloadData]; 
} 

@end 

CustomPagerViewController.m

@interface CustomPagerViewController() 

@end 

@implementation CustomPagerViewController 

- (void)viewDidLoad 
{ 
    // Do any additional setup after loading the view, typically from a nib. 
    [super viewDidLoad]; 

    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"Aardvark"]]; 
    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"Alligator"]]; 
    [self addChildViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"Alpaca"]]; 
} 

@end 

PagerViewController.m

@interface PagerViewController() 
@property (assign) BOOL pageControlUsed; 
@property (assign) NSUInteger page; 
@property (assign) BOOL rotating; 
- (void)loadScrollViewWithPage:(int)page; 
@end 

@implementation PagerViewController 

@synthesize scrollView; 
@synthesize pageControl; 
@synthesize pageControlUsed = _pageControlUsed; 
@synthesize page = _page; 
@synthesize rotating = _rotating; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    [self.scrollView setPagingEnabled:YES]; 
    [self.scrollView setScrollEnabled:YES]; 
    [self.scrollView setShowsHorizontalScrollIndicator:NO]; 
    [self.scrollView setShowsVerticalScrollIndicator:NO]; 
    [self.scrollView setDelegate:self]; 
} 

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { 
    return NO; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return YES; 
} 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    [viewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 
    _rotating = YES; 
} 

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 

    UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    [viewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 

    self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height); 
    NSUInteger page = 0; 
    for (viewController in self.childViewControllers) { 
     CGRect frame = self.scrollView.frame; 
     frame.origin.x = frame.size.width * page; 
     frame.origin.y = 0; 
     viewController.view.frame = frame; 
     page++; 
    } 

    CGRect frame = self.scrollView.frame; 
    frame.origin.x = frame.size.width * _page; 
    frame.origin.y = 0; 
    [self.scrollView scrollRectToVisible:frame animated:NO]; 

} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    _rotating = NO; 
    UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    [viewController didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    for (NSUInteger i =0; i < [self.childViewControllers count]; i++) { 
     [self loadScrollViewWithPage:i]; 
    } 

    self.pageControl.currentPage = 0; 
    _page = 0; 
    [self.pageControl setNumberOfPages:[self.childViewControllers count]]; 

    UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    if (viewController.view.superview != nil) { 
     [viewController viewWillAppear:animated]; 
    } 

    self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height); 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    if ([self.childViewControllers count]) { 
     UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
     if (viewController.view.superview != nil) { 
      [viewController viewDidAppear:animated]; 
     } 
    } 
} 

- (void)viewWillDisappear:(BOOL)animated { 
    if ([self.childViewControllers count]) { 
     UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
     if (viewController.view.superview != nil) { 
      [viewController viewWillDisappear:animated]; 
     } 
    } 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated { 
    UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    if (viewController.view.superview != nil) { 
     [viewController viewDidDisappear:animated]; 
    } 
    [super viewDidDisappear:animated]; 
} 

- (void)loadScrollViewWithPage:(int)page { 
    if (page < 0) 
     return; 
    if (page >= [self.childViewControllers count]) 
     return; 

    // replace the placeholder if necessary 
    UIViewController *controller = [self.childViewControllers objectAtIndex:page]; 
    if (controller == nil) { 
     return; 
    } 

    // add the controller's view to the scroll view 
    if (controller.view.superview == nil) { 
     CGRect frame = self.scrollView.frame; 
     frame.origin.x = frame.size.width * page; 
     frame.origin.y = 0; 
     controller.view.frame = frame; 
     [self.scrollView addSubview:controller.view]; 
    } 
} 

- (void)previousPage { 
    if (_page - 1 > 0) { 

     // update the scroll view to the appropriate page 
     CGRect frame = self.scrollView.frame; 
     frame.origin.x = frame.size.width * (_page - 1); 
     frame.origin.y = 0; 

     UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; 
     UIViewController *newViewController = [self.childViewControllers objectAtIndex:_page - 1]; 
     [oldViewController viewWillDisappear:YES]; 
     [newViewController viewWillAppear:YES]; 

     [self.scrollView scrollRectToVisible:frame animated:YES]; 

     self.pageControl.currentPage = _page - 1; 
     // Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above. 
     _pageControlUsed = YES; 
    } 
} 

- (void)nextPage { 
    if (_page + 1 > self.pageControl.numberOfPages) { 

     // update the scroll view to the appropriate page 
     CGRect frame = self.scrollView.frame; 
     frame.origin.x = frame.size.width * (_page + 1); 
     frame.origin.y = 0; 

     UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; 
     UIViewController *newViewController = [self.childViewControllers objectAtIndex:_page + 1]; 
     [oldViewController viewWillDisappear:YES]; 
     [newViewController viewWillAppear:YES]; 

     [self.scrollView scrollRectToVisible:frame animated:YES]; 

     self.pageControl.currentPage = _page + 1; 
     // Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above. 
     _pageControlUsed = YES; 
    } 
} 

- (IBAction)changePage:(id)sender { 
    int page = ((UIPageControl *)sender).currentPage; 

    // update the scroll view to the appropriate page 
    CGRect frame = self.scrollView.frame; 
    frame.origin.x = frame.size.width * page; 
    frame.origin.y = 0; 

    UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; 
    UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    [oldViewController viewWillDisappear:YES]; 
    [newViewController viewWillAppear:YES]; 

    [self.scrollView scrollRectToVisible:frame animated:YES]; 

    // Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above. 
    _pageControlUsed = YES; 
} 

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
    UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page]; 
    UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
    [oldViewController viewDidDisappear:YES]; 
    [newViewController viewDidAppear:YES]; 

    _page = self.pageControl.currentPage; 
} 

#pragma mark - 
#pragma mark UIScrollViewDelegate methods 

- (void)scrollViewDidScroll:(UIScrollView *)sender { 
    // We don't want a "feedback loop" between the UIPageControl and the scroll delegate in 
    // which a scroll event generated from the user hitting the page control triggers updates from 
    // the delegate method. We use a boolean to disable the delegate logic when the page control is used. 
    if (_pageControlUsed || _rotating) { 
     // do nothing - the scroll was initiated from the page control, not the user dragging 
     return; 
    } 

    // Switch the indicator when more than 50% of the previous/next page is visible 
    CGFloat pageWidth = self.scrollView.frame.size.width; 
    int page = floor((self.scrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1; 
    if (self.pageControl.currentPage != page) { 
     UIViewController *oldViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage]; 
     UIViewController *newViewController = [self.childViewControllers objectAtIndex:page]; 
     [oldViewController viewWillDisappear:YES]; 
     [newViewController viewWillAppear:YES]; 
     self.pageControl.currentPage = page; 
     [oldViewController viewDidDisappear:YES]; 
     [newViewController viewDidAppear:YES]; 
     _page = page; 
    } 
} 

// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    _pageControlUsed = NO; 
} 

// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    _pageControlUsed = NO; 
} 

@end 

Odpowiedz

1

Utwórz identyfikator dla segue (granicę między 2 widoków w konstruktorze Interface)

enter image description here

następnie dodaj następujący kod do AnimalTableViewController

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Animal* animal; 
    if(isFiltered) 
     animal = [filteredTableData objectAtIndex:indexPath.row]; 
    else 
     animal = [allTableData objectAtIndex:indexPath.row]; 

    [self performSegueWithIdentifier:@"DetailSegue" sender:animal]; 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"DetailSegue"]) { 

     PagerViewController *detailVC = [segue destinationViewController]; 
     detailVC.currentAnimal = sender; 
    } 
} 

Następnie w PagerViewController. h Utwórz

@property (strong, nonatomic) Animal *currentAnimal; 

Teraz możesz uzyskać dostęp do zwierzęcia w PagerViewController przez self.currentAnimal

+0

Dziękuję, Roland! Jesteś gwiazdą!Jednakże, gdy klikam na dowolną komórkę, powoduje to, że idę tylko do pierwszego zwierzęcia; jakieś pomysły, jak przejść do konkretnego zwierzęcia? Etykiety komórek mają te same nazwy, co storyboardy, myślałem o zrobieniu tego za pomocą "instrukcji warunkowej" lub "przełącznika", ale to może się skończyć dość długo ... Co sugerowałbyś, że byłoby to najlepsze rozwiązanie? – iOSnewbie

+0

Potrzebujesz nowego kontrolera Viewcontroller dla każdego zwierzęcia? Może powinieneś zrobić 1 viewController i dodać całą logikę tam. Możesz użyć nazwy zwierzęcia, jeśli identyfikatory Segue są takie same. Podobnie jak: [self addChildViewController: [self.storyboard instantiateViewControllerWithIdentifier: self.animal.name]]; –

1

Musisz ustawić przejście z klikniętego UITableViewCell do nowego kontrolera viewController. Użyj metody prepareForSegue i przekaż UIImage (lub tablicę obrazów) do nowego kontrolera viewController. Gdy tablica jest częścią nowego kontrolera viewController, możesz manipulować macierzą w dowolny sposób.

  1. Skonfiguruj nową zmianę z UITableViewCell na viewController.
  2. Ustaw identyfikator segue.
  3. Wyślij viewController obraz (lub tablicę obrazów w twoim przypadku) na podstawie wybranego UITableViewCell 's indexPath.
Powiązane problemy