Ich bin ziemlich neu in der iOS-Programmierung und habe ein Problem, das ich selbst nicht lösen konnte.UITableViewCell Verlinkung zu einer bestimmten Seite in PageViewController
Der Hauptteil meiner App ist eine Liste von Tieren (AnimalTableViewController), die durchsuchbar ist (diese Funktion funktioniert). Nachdem Sie auf eine bestimmte Zelle geklickt haben, sollten Sie ein Bild eines Tieres sehen können. Alle Tierbilder werden im PagerViewController (CustomPagerViewController) kompiliert.
image of my storyboards can be found here http://i50.tinypic.com/ve14r4.jpg
Was muss ich tun, ist eine dynamische Tabellenzelle auf eine bestimmte Ansicht/Storyboard zu verbinden. Ich konnte schon vorher eine Zelle mit einem Bild verbinden - das Array von Bildern wurde in einem einzigen View-Controller angezeigt. Ich habe es dieses Mal über PagerViewController gemacht, weil ich die Swipe-Funktion benötigte (Swipe-bezogene Methoden befinden sich im PagerViewController.m und alle funktionieren wie erwartet).
Bitte helfen Sie mir dabei, ich habe keine Anleitungen oder Ratschläge gefunden, wie Daten zwischen UITableView und PagerViewController übertragen werden können.
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
Vielen Dank, Roland! Du bist ein Star!Wenn ich jedoch auf eine Zelle klicke, muss ich nur zum ersten Tier gehen. irgendwelche Ideen, wie man zu einem bestimmten Tier springt? Die Zellenbezeichnungen sind die gleichen Namen wie die Storyboards. Ich habe mir überlegt, ob ich das durch 'if conditional statement' oder 'switch' machen könnte, aber das könnte ziemlich lange dauern ... Was schlägst du vor, wäre die beste Lösung? – iOSnewbie
Benötigen Sie einen neuen Viewcontroller für jedes Tier? Vielleicht solltest du 1 viewController machen und dort alle Logik hinzufügen. Sie können einfach den Namen des Tieres verwenden, wenn die Segue-Identifikatoren identisch sind. Wie: [self addChildViewController: [self.storyboard instantiateViewControllerWithIdentifier: self.animal.name]]; –