I have a double-tap gesture on a view controller iRpImageViewerViewController (topmost on the navigation stack), and each time a view on iRpImageViewerViewController is double-tapped, it pushes a image editor view controller iRpImageEditorViewController onto the stack, that's why there are several of them, none of which appeared. Each time I double-tap, it's added, but never appears. self is simply the class that houses this double-tap gesture iRpImageViewerViewController, and does in fact have a navigationController per the LLDB output
po self.navigationController returns a navigation controller as expected.
po self.navigationController viewControllers shows a new view controller being added to the list with each pushViewController statement encountered, yet the pushed item won't show up on screen.
I shouldn't have to push and then move to front, right?? Doesn't the push automatically make it the frontmost view controller?
Note that my navigation controller is NOT the root controller in my hierarchy, starting from the window. I have a full screen map view controller, then a half-screen 'dashboard' view controller, then within that I have a window on the dashboard that has a picture, and that picture is itself a view controller. So starting with the picture view controller, shown here, you can walk through everything that happens
#implementation iRpDashboardHeaderImagesViewController
{
IGGridView *theGridViewControl;
UIView *theGridParentView;
iRpImageSet *thePropertyImageSet;
iRpDashboardViewController *dashboardViewController;
UIImageView *primaryImageMarker;
UINavigationController *imageEditorNavController;
iRpImageViewerViewController *imageViewerVC;
}
-(id)initWithParentViewController:(iRpDashboardViewController*)parentController
{
self = [super init];
if (self)
{
dashboardViewController = parentController;
}
return self;
}
-(void)loadView
{
// Just a basic size to get started... the final size is set later in another method. I believe actual height will be 220
CGRect theGridRectangle = CGRectMake(0, 0, 375, 220);
theGridViewControl = [[IGGridView alloc]initWithFrame:theGridRectangle style:IGGridViewStyleSingleCellPaging];
// Set additional properties to configure the grid view
theGridViewControl.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
theGridViewControl.selectionType = IGGridViewSelectionTypeCell;
theGridViewControl.contentMode = UIViewContentModeScaleAspectFit;
theGridViewControl.allowHorizontalBounce = NO;
theGridViewControl.alwaysBounceVertical = NO;
self.view = theGridViewControl;
}
-(void)viewDidLoad
{
[super viewDidLoad];
imageEditorNavController = [[UINavigationController alloc] init];
}
-(void)presentImageViewerForCellAtPath:(IGCellPath*)path
{
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:path.columnIndex];
imageViewerVC = [[iRpImageViewerViewController alloc] initWithParentViewController:self imageSet:thePropertyImageSet initialImageAndMedia:imageAndMediaItem];
imageViewerVC.edgesForExtendedLayout = UIRectEdgeNone;
imageViewerVC.navigationItem.title = dashboardViewController.parcelNbr;
imageViewerVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
// Create a navigation controller to embed the image viewer view controller inside.
[imageEditorNavController pushViewController:imageViewerVC animated:YES];
[self presentViewController:imageEditorNavController animated:YES completion:^(void)
{
}];
}
-(void)imageEditorDone
{
[self dismissViewControllerAnimated:YES completion:^{}];
}
}
...
#implementation iRpImageViewerViewController
{
IGGridView *theMainImageGridviewControl;
iRpImageSet *thePropertyImageSet;
iRpImageFilmstripViewController *theFilmstripViewController;
iRpImageAndMedia *initialMediaItem;
UIImageView *primaryImageMarker;
iRpImageEditorViewController *imageEditorVC;
UIViewController *theParentViewController;
}
-(id)initWithParentViewController:(UIViewController*)parentViewController imageSet:(iRpImageSet*)imageSet initialImageAndMedia:(iRpImageAndMedia*)imageAndMedia
{
self = [super initWithNibName:#"iRpImageViewerViewController" bundle:nil];
if (self)
{
theParentViewController = parentViewController;
theFilmstripViewController = [[iRpImageFilmstripViewController alloc] initWithParentViewController:self imageSet:imageSet initialImageAndMedia:imageAndMedia];
initialMediaItem = imageAndMedia;
thePropertyImageSet = imageSet;
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
theMainImageGridviewControl = [[IGGridView alloc]initWithFrame:self.mainImagePlaceholderView.frame style:IGGridViewStyleSingleCellPaging];
// Set additional properties to configure the grid view
theMainImageGridviewControl.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
theMainImageGridviewControl.selectionType = IGGridViewSelectionTypeCell;
theMainImageGridviewControl.contentInset = UIEdgeInsetsZero;
theMainImageGridviewControl.allowHorizontalBounce = NO;
theMainImageGridviewControl.alwaysBounceHorizontal = NO;
theMainImageGridviewControl.alwaysBounceVertical = NO;
[self.mainImagePlaceholderView addSubview:theMainImageGridviewControl];
[self addAChildViewController:theFilmstripViewController toViewWithTag:self.filmstripPlaceholderView.tag];
}
-(void)addGestureRecognizersToCell:(IGGridViewImageCell*)cell
{
static NSMutableArray *recognizers;
UITapGestureRecognizer *doubleTapRecognizer;
UILongPressGestureRecognizer *longPressRecognizer;
if (!recognizers)
{
recognizers = [[NSMutableArray alloc] init];
doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTapRecognizer:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPressRecognizer:)];
[recognizers addObject:doubleTapRecognizer];
[recognizers addObject:longPressRecognizer];
}
// Don't do anything because already processed.
[cell removeGestureRecognizer:doubleTapRecognizer];
[cell removeGestureRecognizer:longPressRecognizer];
[cell registerGestures:recognizers];
}
-(void)handleDoubleTapRecognizer:(UITapGestureRecognizer*)recognizer
{
NSLog(#"Double Tapped on ImageViewerViewController's main image, so opening editor");
IGCellPath *pathForCurrentCell = [self pathForCurrentCell];
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:pathForCurrentCell.columnIndex];
imageEditorVC = [[iRpImageEditorViewController alloc] initWithImageAndMediaItem:imageAndMediaItem];
imageEditorVC.navigationItem.title = #"Photo Details Editor";
imageEditorVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
imageEditorVC.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController pushViewController:imageEditorVC animated:YES];
}
-(void)imageEditorDone
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(void)imageEditorCancelled
{
[self dismissViewControllerAnimated:YES completion:nil];
}
}
...
This class below is the one that keeps being added to the navigation controller, but never appears.
...
#implementation iRpImageEditorViewController
{
__weak IBOutlet UISwitch *primarySwitch;
__weak IBOutlet UISwitch *postToWebSwitch;
__weak IBOutlet UITextView *descriptionView;
__weak IBOutlet UIImageView *imageView;
__weak IBOutlet UITextField *mediaDate;
__weak IBOutlet UITextField *orderNbr;
__weak IBOutlet UITextField *updatedBy;
__weak IBOutlet UITextField *updateDate;
iRpImageAndMedia *theImageAndMediaItem;
}
-(id)initWithImageAndMediaItem:(iRpImageAndMedia*)imageAndMediaItem
{
if (self = [super initWithNibName:#"iRpImageEditorViewController" bundle:nil])
{
theImageAndMediaItem = imageAndMediaItem;
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self populateUserInterface];
}
-(void)populateUserInterface
{
imageView.image = [theImageAndMediaItem pictureForViewOfSize:imageView.bounds.size];
primarySwitch.on = [theImageAndMediaItem isPrimary];
postToWebSwitch.on = [[theImageAndMediaItem.mediaManagedObj valueForKey:#"postToWeb"] boolValue];
descriptionView.text = [theImageAndMediaItem.mediaManagedObj valueForKey:#"desc"];
updatedBy.text = [theImageAndMediaItem.mediaManagedObj valueForKey:#"updatedBy"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
[dateFormat setTimeZone:[NSTimeZone localTimeZone]];
NSString *theFormattedDate = [dateFormat stringFromDate:[theImageAndMediaItem.mediaManagedObj valueForKey:#"updateDate"]];
updateDate.text = theFormattedDate;
orderNbr.text = [[theImageAndMediaItem.mediaManagedObj valueForKey:#"order"] stringValue];
}
-(IBAction)postToWebValueChanged:(id)sender
{
UISwitch *theSwitch = sender;
[theImageAndMediaItem.mediaManagedObj setValue:[NSNumber numberWithBool:theSwitch.on] forKey:#"postToWeb"];
}
-(IBAction)primaryValueChanged:(id)sender
{
UISwitch *theSwitch = sender;
[theImageAndMediaItem.mediaManagedObj setValue:[NSNumber numberWithBool:theSwitch.on] forKey:#"primary"];
}
...
-(void)handleDoubleTapRecognizer:(UITapGestureRecognizer*)recognizer
{
NSLog(#"Double Tapped on ImageViewerViewController's main image, so opening editor");
IGCellPath *pathForCurrentCell = [self pathForCurrentCell];
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:pathForCurrentCell.columnIndex];
imageEditorVC = [[iRpImageEditorViewController alloc] initWithImageAndMediaItem:imageAndMediaItem];
imageEditorVC.navigationItem.title = #"Photo Details Editor";
imageEditorVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
imageEditorVC.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController pushViewController:imageEditorVC animated:YES];
}
Related
I can't figure out how did this happened.But there is something i have done may cause it.
1,I have swizzled viewDidLoad & viewDidAppear in UIViewController.
2,The AppDelegate's window's rootViewController is a mainViewController(UIViewController).
And I add customNavigationController.view to mainViewController.view.
CustomNavigationController's rootViewController is a UITabbarController.
3,Thread problem?
4,This happened randomly when i tap and pan on the screen frequently.
Here is My code :
In my Custom UITabBarController
- (void)loadViewControllers {
HomeViewController *homeVC = [[HomeViewController alloc] init];
[homeVC.tabBarItem setImage:[UIImage imageNamed:#"Home"]];
[homeVC.tabBarItem setTitle:homeTab];
ProductsViewController *productsVC = [[ProductsViewController alloc] init];
[productsVC.tabBarItem setImage:[UIImage imageNamed:#"Products"]];
[productsVC.tabBarItem setTitle:productsTab];
DiscoverViewController *discoverVC = [[DiscoverViewController alloc] init];
[discoverVC.tabBarItem setImage:[UIImage imageNamed:#"Discover"]];
[discoverVC.tabBarItem setTitle:discoverTab];
AssetsMainViewController *assetsVC = [[AssetsMainViewController alloc] init];
[assetsVC.tabBarItem setImage:[UIImage imageNamed:#"Assets"]];
[assetsVC.tabBarItem setTitle:assetsTab];
NewsViewController *newsVC = [[NewsViewController alloc] init];
[newsVC.tabBarItem setImage:[UIImage imageNamed:#"News"]];
[newsVC.tabBarItem setTitle:newsTab];
[self setViewControllers:#[homeVC,productsVC, discoverVC, assetsVC, newsVC]];
}
In mainViewController:
- (void)loadViewController {
TJSNavigationController *rootNavi = [[TJSNavigationController alloc] initWithRootViewController:[TJSTabBarController sharedSingleton]];
[rootNavi.view setFrame:CGRectMake(0, 0, tMeasure_Width_Sreen, tMeasure_Height_Screen)];
[self.view addSubview:rootNavi.view];
[[TJSTabBarController sharedSingleton] loadViewControllers];
[[TJSTabBarController sharedSingleton] setDelegate:self];
}
After had many research, I don't find solution.So that I decided post my question. I have an ** IBOutlet UITextField *txtUsername at DetailViewController.h. At FormViewController I have a UIScrollview, and then I add [self.scrollView addSubview:DetailView.view]. The problem is when stand at DetailViewController.m I call txtUsername.text it return a nil value. Any suggestion?
It seems that you are trying to embed one view controller within another. I recommend using a Container view and then loading DetailViewController into that. Simply adding the view, as you are in your code, is not going to be enough. You probably want all the behavior in DetailViewController to work.
After debug many time I found the problem is:
At FormViewController I have method:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"Add new user";
DetailView = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
}
return self;
}
And method (Which had call at viewDidLoad)
-(void) loadViewBySegment {
[DetailView.view removeFromSuperview];
[self.scrollView addSubview:DetailView.view];
}
and ViewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(save)];
self.navigationItem.rightBarButtonItem = saveButton;
if(user)
{
userDetailView.user = user;
}
[self loadViewBySegment];
// Do any additional setup after loading the view from its nib.
}
and
-(void)save{
[[userDetailView userDetailInstance] insertData];
}
And then at DetailViewController I create insertData function
-(void)insertData{
User *object = [[User alloc] init];
object.Username = txtUsername.text;
object.FullName = txtFullname.text;
object.Title = txtTitle.text;
object.Role = [NSNumber numberWithInt:[txtRole.text intValue]];
object.UserInitial =txtInital.text;
object.Status = YES;
object.AddedTime = [NSDate date];
object.UpdatedTime = [NSDate date];
object.Phone = #"0949931124";
object.Password = #"123456";
[[DBManager sharedInstant] insertData:BUsers item:[object dictionary] target:self];
}
The reason why texfield.text is nil:
At FormViewController I call an instance of DetailViewController it's mean DetailViewController - will be have new alloc init. so that textfield's value will which had enter by user before will be reset.
The right way I need to do is: change the save function at FormViewController:
-(void)save{
[DetailView insertData];
}
P/S:Lesson Learn for me is: be careful when use Instace (Singleton Design partner).
I have a UITableView which has some custom styling. This table view appears in two places in the app, one of which is inside a UIPopoverController. However when the tableview is inside the popover it takes on the default tableview styling as stated in the UI Transition Guide under "Popover".
The problem I have is that there appears to be nowhere to change this behaviour. Regardless of where I try and modify properties of the tableview the view inside the popover doesn't change.
Anyone dealt with this issue before or have any ideas?
Here is the init method of LibraryProductView where I create the table view:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.sectionOrdering = [NSArray arrayWithObjects:
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DESCRIPTION],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DOCUMENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_ACTIVE_INGREDIENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_PRODUCTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_DOCUMENTS], nil];
self.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:CGRectInset(self.bounds, 10, 0) style:UITableViewStyleGrouped];
self.tableView.backgroundColor = [UIColor whiteColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.showsVerticalScrollIndicator = NO;
[self addSubview:self.tableView];
}
return self;
}
Here is where the containing view (LibraryProductView) is added to the popover:
- (IBAction)didTouchInformationButton:(id)sender
{
if (_infoPopover != nil && _infoPopover.isPopoverVisible)
{
[_infoPopover dismissPopoverAnimated:YES];
return;
}
CGSize preferredSize = CGSizeMake(600.0f, 500.0f);
LibraryProductViewController* productController = [[[LibraryProductViewController alloc] initWithPreferredSize:preferredSize] autorelease];
productController.filterByMyCompany = NO;
productController.product = _activityInput.product;
UINavigationController* nav = [[[UINavigationController alloc] initWithRootViewController:productController] autorelease];
nav.title = _activityInput.product.name;
RELEASE(_infoPopover);
_infoPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
_infoPopover.popoverContentSize = CGSizeMake(preferredSize.width, preferredSize.height + 46);
[_infoPopover presentPopoverFromRect:_infoButton.frame inView:_infoButton permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
The LibraryProductView is created within viewDidLoad method of LibraryProductViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.libraryProductView = [[LibraryProductView alloc] initWithFrame:(usingPreferredSize ? CGRectMake(0.0, 0.0, preferredSize.width, preferredSize.height) : self.view.bounds)];
self.libraryProductView.dataSource = self;
self.libraryProductView.delegate = self;
[self.view addSubview:self.libraryProductView];
}
To set properties for the TableView you might do so in
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
[tableView setBackgroundColor:[UIColor redcolor]];
[tableView setSeparatorColor: [UIColor blueColor]];
return 1;
}
This, of course, assumes you have set UITableViewDataSource in your .h file
I want to reset zoom factor applied to imageView/scrollView before calling viewControllerAfterViewController.
I have an UIPageViewController "SecondViewController" and another UIViewController "ImageViewController". To explain hierarchy I prefer show some code :
#import "ImageViewController.h"
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize pageViewController;
#synthesize imgModelArray;
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return imgModelArray.count;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[self view] setBackgroundColor:[UIColor colorWithRed: 40/255.0 green:40/255.0 blue:40/255.0 alpha:1.0]];
// Init model and pageViewController
self.imgModelArray = [NSMutableArray arrayWithObjects:
[[ImageModel alloc] initWith:#"piaggo.jpg":#"softCat"],
[[ImageModel alloc] initWith:#"crumble.jpg":#"funnyDog"],
[[ImageModel alloc] initWith:#"piaggo.jpg":#"sleepingCat"],
[[ImageModel alloc] initWith:#"crumble.jpg":#"goodDog"],
[[ImageModel alloc] initWith:#"piaggo.jpg":#"softCat"],
[[ImageModel alloc] initWith:#"crumble.jpg":#"funnyDog"],
[[ImageModel alloc] initWith:#"piaggo.jpg":#"sleepingCat"],
[[ImageModel alloc] initWith:#"crumble.jpg":#"goodDog"], nil];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:50.0f] forKey:UIPageViewControllerOptionInterPageSpacingKey]];
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;
// Init ImageViewController - Load Model - Create page 1
ImageViewController *imageViewController = [[ImageViewController alloc] init];
imageViewController.model = [imgModelArray objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:imageViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
[self addChildViewController:pageViewController];
[self.view addSubview:pageViewController.view];
[pageViewController didMoveToParentViewController:self];
self.view.gestureRecognizers = pageViewController.gestureRecognizers;
}
// Return an ImageViewController with previous data model
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)vcFrom
{
ImageViewController *imgVc = (ImageViewController *)vcFrom;
NSUInteger currentIndex = [imgModelArray indexOfObject:[imgVc model]];
if (currentIndex == 0)
{
return nil;
}
ImageViewController *previousImgViewController = [[ImageViewController alloc] init];
previousImgViewController.model = [imgModelArray objectAtIndex:currentIndex - 1];
return previousImgViewController;
}
// Return an ImageViewController with next data model
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)vcFrom
{
ImageViewController *imgVc = (ImageViewController *)vcFrom;
[imgVc zoomX1];
NSUInteger currentIndex = [imgModelArray indexOfObject:[imgVc model]];
if (currentIndex == imgModelArray.count - 1)
{
return nil;
}
ImageViewController *nextImgViewController = [[ImageViewController alloc] init];
nextImgViewController.model = [imgModelArray objectAtIndex:currentIndex + 1];
return nextImgViewController;
}
#end
I want to call zoomX1 method (localized in ImageViewController.m), just before this one : "viewControllerAfterViewController"
What kind of event could do this ?
zoomX1 work well excepted when I am using viewControllerAfterViewController.
When I call zoomx1 inside "viewControllerAfterViewController", my view is disappearing...
But the values for height and width are not 0. Help me please !
In ImageViewController.m : zoomX1
- (void)zoomX1{
// Figure out the rect we want to zoom to, then zoom to X1
UIImage *currentImage = [UIImage imageNamed:model.imageName];
CGSize currentImgSize = currentImage.size;
CGFloat w = currentImgSize.width;
CGFloat h = currentImgSize.height;
CGFloat x = 0;
CGFloat y = 0;
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
[self.scrollView zoomToRect:rectToZoomTo animated:YES];
}
EDITED (2X) :
I think I have a problem with UIPanGestureRecognizer.
In "SecondViewController.view" and "pageViewController" : PanGesture is used to move to next/previous "ImageViewController" with "viewControllerAfterViewController" and "viewControlleBeforeViewController"
In "ImageViewController.scrollView" : PanGesture is used to move to a specific area when I zoomed on an image.
I didn't add programmatically a PanGesture. I just want to keep the panGesture inside scrollView which is reponsible of moving inside an Image. And keep the other panGesture linked at view level which is responsible of switching page. I think they are private Apple's method.
But when I pan inside scrollView there is a problem.
I had a similar problem in one of my projects and what I did I added an extra target to the UISwipeGestureRecognizer of the UIPageViewController. You can try this (it may be a considered by other developers a hack but I don't think so).
In viewDidLoad or other init/setup methods you can try something like this:
for(UIGestureRecognizer *gesture in yourPageViewController.gestureRecognizers) {
if([gesture isKindOfClass:[UISwipeGestureRecognizer class]]) {
[gesture addTarget:self action:#selector(zoomX1)]
}
}
I watched the WWDC video on UIViewController Containment and read through this blog post: http://www.cocoanetics.com/2012/04/containing-viewcontrollers/
but I can't get my initial view controller to show. Is there something I am missing? In my ContainerViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_homeViewController = [[HomeViewController alloc] init];
_detailViewController = [[DetailViewController alloc] init];
[self setSubViewControllers:#[_homeViewController, _detailViewController]];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (_selectedViewController.parentViewController == self) {
// nothing to do
return;
}
// adjust the frame to fit the container view
_selectedViewController.view.frame = _containerView.bounds;
// make sure that it resizes on rotation automatically
_selectedViewController.view.autoresizingMask = _containerView.autoresizingMask;
// add as child VC
[self addChildViewController:_selectedViewController];
// add it to container view, calls willMoveToParentViewController for us
[_containerView addSubview:_selectedViewController.view];
// notify that move is done
[_selectedViewController didMoveToParentViewController:self];
}
- (void)loadView {
// set up the base view
CGRect frame = [[UIScreen mainScreen] bounds];
UIView *aView = [[UIView alloc] initWithFrame:frame];
aView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
aView.backgroundColor = [UIColor blueColor];
// set up content view
_containerView = [[UIView alloc] initWithFrame:frame];
_containerView.backgroundColor = [UIColor grayColor];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[aView addSubview:_containerView];
self.view = aView;
}
- (void)setSubViewControllers:(NSArray *)subViewControllers {
_subViewControllers = [subViewControllers copy];
if (_selectedViewController) {
// remove previous VC
}
_selectedViewController = _subViewControllers[0];
}
My ContainerViewController is the initial view controller in my storyboard. I see that it shows on the simulator, but the HomeViewController (the first child view controller in my container) does not show.
When I step through the debugger, the subViewControllers property of my ContainerViewController does have the homeViewController and detailViewController in it. The viewDidLoad of HomeViewController also does get called. I just don't see anything on screen except the background color of the ContainerViewController.
Any thoughts? Thanks.
So I'm not the brightest person in the world, but the reason nothing was being shown on the screen was because the nibs were in the storyboard and I needed to do this instead:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
_homeViewController = [storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
_detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
Hopefully this helps someone who is also not familiar with Storyboards yet.
You have an NSArray, but you are trying to access it as a C array.
_subViewControllers[0]
should be:
[_subViewControllers objectAtIndex:0];
That being said, you seem to have some code that could be better in other methods. I would personally clean this up a lot and make it much simpler. I would remove loadView and _containerView, and just use self.view as one normally would. For what you are trying to do, there really doesn't even seem a need to track parent and child view controllers. Anyway, this is how I would do it:
#interface ContainerViewController ()
#property (nonatomic, retain) NSArray *subViewControllers;
#end
#implementation ObservationReportViewController {
UIViewController *_selectedViewController;
}
#synthesize subViewControllers = _subViewControllers;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
HomeViewController *homeViewController = [[HomeViewController alloc] init];
homeViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
DetailViewController *detailViewController = [[DetailViewController alloc] init];
detailViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Retain the view controllers.
self.subViewControllers = #[homeViewController, detailViewController];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setSelectedViewController: [_subViewControllers objectAtIndex:0]];
}
-(void)setSelectedViewController:(UIViewController *)selectedViewController {
if (_selectedViewController != selectedViewController) {
[_selectedViewController.view removeFromSuperview];
_selectedViewController = selectedViewController;
// adjust the frame to fit the container view
[self.view addSubview:_selectedViewController.view];
//_selectedViewController.view.frame = _containerView.bounds;
_selectedViewController.view.frame = self.view.bounds;
}
}
If you set the InitialViewController through the storyboard in a different storyb than the MainStoryboard, then you need to update the project settings to use that new storyboard.
Go to project settings, General and set the Main Interface setting to the new storyboard