Skip navigation

calling a -void from another ViewController

808 Views 6 Replies Latest reply: Jul 14, 2011 4:49 PM by james_coleman01 RSS
james_coleman01 Calculating status...
Currently Being Moderated
Jul 12, 2011 4:51 PM

Developers,

 

I need some help with a project (which can be downloaded from this link: files.me.com/medical_student_apps/dvas5s ).

 

I have a UIViewController (testAppViewController) that contains a scrollView - paging enabled.  Each view within the scrollView is loaded from a separate viewController (e.g. viewController0, viewcontroller1 etc).

 

In viewController0 I have an IBAction that i hoped would activate a method -(void) LoadView in the testAppViewController .  Unfortunately, I have not been able to get this working.  My NSlog shows that the initial action in viewController0 is called, but the LoadView method in testAppViewController does not activate.

 

How can i get this working?

 

james

 

Code:

 

testAppViewController.h

 

#import <UIKit/UIKit.h>
@class ViewController0;
 
@interface testAppViewController : UIViewController <UIScrollViewDelegate> {
    UIScrollView *scrollView;
    UIPageControl *pageControl;
    NSMutableArray *viewControllers;
    BOOL pageControlUsed;
}
 
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
@property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
@property (nonatomic, retain) NSMutableArray *viewControllers;
@property (nonatomic, retain) ViewController0 *viewController;
 
-(void)LoadView;
 
@end
 
 
 

 

testAppViewController.m

 

#import "testAppViewController.h"
#import "ViewController0.h"
#import "ViewController2.h"
#import "ViewController1.h"
static NSUInteger kNumberOfPages = 3;
 
@interface testAppViewController (PrivateMethods)
 
- (void)loadScrollViewWithPage:(int)page;
- (void)scrollViewDidScroll:(UIScrollView *)sender;
 
@end
 
@implementation testAppViewController
 
@synthesize scrollView, pageControl, viewControllers, viewController;
 
- (void)dealloc {
    [viewControllers release];
    [viewController release];
    [scrollView release];
    [pageControl release];
    [super dealloc];
}
 
 
-(void)viewDidLoad {
 
 
    [[self navigationController] setNavigationBarHidden:YES animated:NO];
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i < kNumberOfPages; i++) {
        [controllers addObject:[NSNull null]];
    }
    self.viewControllers = controllers;
    [controllers release];
 
    scrollView.pagingEnabled = YES;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.scrollsToTop = NO;
    scrollView.delegate = self;
 
    pageControl.numberOfPages = kNumberOfPages;
    pageControl.currentPage = 0;
 
    [self loadScrollViewWithPage:0];
    [self loadScrollViewWithPage:1];
    [self loadScrollViewWithPage:2];
}
 
- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= kNumberOfPages) return;
 
    ViewController0 *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        NSString *className = [NSString stringWithFormat:@"ViewController%d", page];
        Class myClass = NSClassFromString(className);
        controller = [[myClass alloc] initWithNibName:className bundle:nil];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
 
    }
 
    if (nil == controller.view.superview) {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];
    }
}
 
- (void)scrollViewDidScroll:(UIScrollView *)sender {
    if (pageControlUsed) {
        return;
    }
    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    pageControl.currentPage = page;
 
    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];
 
}
 
 
 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;
}
 
- (IBAction)changePage:(id)sender {
    int page = pageControl.currentPage;
    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [scrollView scrollRectToVisible:frame animated:YES];
    pageControlUsed = YES;
}
 
-(void)LoadView{
    NSLog(@"thisViewwillNowLoad");
}
 
 
 
@end

 

 

viewController0.h

 

#import <UIKit/UIKit.h>
 
@class testAppViewController;
 
@interface ViewController0 : UIViewController {
 
}
 
@property (nonatomic, retain) testAppViewController *testAppVC;
 
-(IBAction)action0;
 
 
@end
 

 

 

viewController0.m

 

#import "ViewController0.h"
#import "testAppViewController.h"
 
@implementation ViewController0
@synthesize testAppVC;
 
 
-(IBAction)action0{
    [testAppVC LoadView];
    NSLog(@"action0 called");
}
 
 
@end
  • Llessur999 Level 4 Level 4 (1,145 points)
    Currently Being Moderated
    Jul 12, 2011 6:14 PM (in response to james_coleman01)

    james_coleman01 wrote:

     

        [testAppVC LoadView];
        NSLog(@"action0 called");
    

     

    testAppVC is nil at this point.  I don't see that you are ever initializing testAppVC.  You need to set testAppVC to a value of type testAppViewController before invoking LoadView.  If an instance of that class doesn't already exist, you must create it.  [BTW, having a class name that starts with a lower-case letter will definitely lead to confusion.  Recommend renaming class testAppViewController to TestAppViewController.]

     

    The code to load a view controller typically looks like something like this.  Even if you aren't using a navigation controller, the first line is applicable.

        TestAppViewController *testAppViewController = [[TestAppViewController alloc] initWithNibName:@"TestAppViewController" bundle:nil];

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

        [testAppViewController release];

  • Llessur999 Level 4 Level 4 (1,145 points)
    Currently Being Moderated
    Jul 12, 2011 9:07 PM (in response to james_coleman01)

    I think I see what you are trying to do.  In any case, the problem is the same.  You must set property testAppVC before referencing it.  Add this to [testAppViewController loadScrollViewWithPage] immediately after you initialize controller using initWithNibName.

     

    if ([controller respondsToSelector:@selector(setTestAppVC:)]) {

        [controller performSelector:@selector(setTestAppVC:) withObject:self];

    }


    It won't cause any immediate problems, but you are defining controller as type ViewController0 then later initializing it with type ViewController0, ViewController1, or ViewController2 depending on the page.  Variable controller should be of type UIViewController, or you should create a parent class for your three view controllers.  The latter approach would be appropriate if all three view controllers have common properties such as as testAppVC.  Push those properties up to the parent.

  • Steve Herman1 Level 4 Level 4 (2,545 points)
    Currently Being Moderated
    Jul 12, 2011 9:25 PM (in response to james_coleman01)

    Llessur999 is correct.  Your declaration only says that testAppVC is a variable that can point to a testAppViewController. But you never initialize it to point at at one so it's still nil when your action0 method executes.

     

    Here's one way to fix your problem...

     

    First, in ViewController0.h, you should include a declaration of your testAppVC instance variable inside the curly braces of your interface declaration. Like this:

     

    @interface ViewController0 : UIViewController {

      testAppViewController *testAppVC;

    }

     

    The @property line you have below the curly braces may make the above declaration somewhat "optional" but I believe it's more correct to include both.

     

    Now, in your loadScrollViewWithPage: method in testAppViewController.m you load each of your three ViewControllers... and when page == 0 you're loading your ViewController0. So while you've got a pointer to your ViewController0 you can use that opportunity to initialize it's testAppVC pointer to point back to the testAppViewController. Like this:

     

      ...

      controller = [[myClass alloc] initWithNibName:className bundle:nil];

      if (page == 0)                           //  Add this

           [controller setTestAppVC:self];     //  Add this

      ...

     

     

    Steve

     

    PS - I also agree with  Llessur999 that you should try to follow the naming conventions... your class names should begin with an uppercase (so testAppViewController should be TestAppViewController) and method names should begin with a lowercase (so LoadView should be loadView).

     

    PPS - From the wording of your questions it sounds like you're under the impression that the fact that LoadView returns (void) has something do to with your problem... but it really doesn't.

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.