For some reason I'm having trouble displaying a view from a secondary view controller in my application.
My main view controller calls another view controller that's responsible for loading a pdf view.
The code in MainViewController looks like this:
- (int)openPDF
{
[self loadSettingsWithDefaults];
RDPDFViewController *m_pdf;
if( m_pdf == nil )
{
m_pdf = [[RDPDFViewController alloc] initWithNibName:#"RDPDFViewController"bundle:nil];
}
int result = [m_pdf PDFOpen:#"/Users/steve/test.pdf" withPassword:#""];
if(result == 1)
{
m_pdf.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:m_pdf animated:YES];
}
return result;
}
This code is located in the second view. This is the method referred to above in MainViewController.
- (int)PDFOpen:(NSString *)path withPassword:(NSString *)pwd {
[self PDFClose];
PDF_ERR err = 0;
m_doc = [[PDFDoc alloc] init]; err = [m_doc open:path :pwd]; switch( err )
{
case err_ok: break;
case err_password: return 2;
break; default: return 0;
}
CGRect rect = [[UIScreen mainScreen]bounds];
//GEAR
if (![self isPortrait] && rect.size.width < rect.size.height) { float height = rect.size.height;
rect.size.height = rect.size.width;
rect.size.width = height;
}
//END
if(SYS_VERSION>=7.0) {
m_view = [[PDFView alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, rect.size.height)]; }
else
{
m_view = [[PDFView alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, rect.size.height-20-44)];
}
[m_view vOpen :m_doc :(id<PDFViewDelegate>)self];
pagecount = [m_doc pageCount];
[self.view addSubview:m_view];
return 1; }
When the code executes, I know the view object is being created as I can see debug output coming from it in the console. However it will not display the new view in the iPhone simulator.
Feel free to provide feedback--just remember this is my first StackOverflow post! I'll be happy to provide more info as needed.
My main view controller was set to be the root view controller for my application. I had to set the navigation controller to be the root view controller, and then add the other view controllers after that.
After that I told navController to pop to the root view controller.
navController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
[navController setNavigationBarHidden:YES];
[navController popToRootViewControllerAnimated:YES];
Related
I have a problem with my UIScrollView and I hope some of you can help me in some way.
I explain you ...
At the center of my ViewController I have a ScrollView showing the contents of 3 external UIViewController. Through classic for loops I am able to properly display the contents and so far I have not found any problems ...
The problem arises when I perform scrolling between the view controller (horizontally) or, the content of each view controller moves, it does not remain as it was initially set. Now I can not figure out if the problem depends ScrollView or by content, but I think it is a problem of content viewcontroller because I used the autolayout to set constraints ...
At this point I think it's a problem that arises in the ScrollView when I make scrolling to show the next viewcontroller.
Below I insert the screen shoots to show my situation .. as you can see the contents are moved to the right and do not remain in the X position zero.
Can you help me figure out where I'm wrong? what code and 'wrong ..
ScreenShoot
code used
-(void)initializeViewControllerTour {
/* Inserisce in una NSMutableArray i ViewController inizializzati da utilizzare*/
_a_TourVC = [[UPATour alloc] init];
_a_TourVC = [self.storyboard instantiateViewControllerWithIdentifier:#"A_Tour_App"];
_b_TourVC = [[UPBTour alloc] init];
_b_TourVC = [self.storyboard instantiateViewControllerWithIdentifier:#"B_Tour_App"];
_c_TourVC = [[UPCTour alloc] init];
_c_TourVC = [self.storyboard instantiateViewControllerWithIdentifier:#"C_Tour_App"];
_containerArrayVC = [[NSMutableArray alloc] init];
[_containerArrayVC addObject:_a_TourVC];
[_containerArrayVC addObject:_b_TourVC];
[_containerArrayVC addObject:_c_TourVC];
NSInteger index = 0;
/* Imposta i valori per la ScrollView */
CGSize scrollViewSize = CGSizeMake([_containerArrayVC count] * _scrollView.frame.size.width, _scrollView.frame.size.height);
_scrollView.contentSize = scrollViewSize;
_scrollView.scrollEnabled = YES;
_scrollView.showsVerticalScrollIndicator = NO;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.pagingEnabled = YES;
_scrollView.delegate = self;
/* Imposta il PageControl */
_pageControl.userInteractionEnabled = NO;
_pageControl.numberOfPages = [_containerArrayVC count];
_pageControl.currentPage = index;
/* Crea il ciclo For per i ViewController basandosi sulla MutableArray */
for (_currentViewController in _containerArrayVC) {
[self addChildViewController:_currentViewController];
CGFloat originx = (index) * _scrollView.frame.size.width;
_currentViewController.view.frame = CGRectMake(originx, 0, _scrollView.frame.size.width, _scrollView.frame.size.height);
[_scrollView addSubview:_currentViewController.view];
[_currentViewController didMoveToParentViewController:self];
index ++;
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageW = _scrollView.frame.size.width;
CGFloat segmentPage = _scrollView.contentOffset.x / pageW;
NSInteger page = lround(segmentPage);
_pageControl.currentPage = page;
}
I want to present a modal view controller. In iOS7 everything runs fine but in iOS8 the frame of view controller is changed. I read some answers and one of the solutions is to set the preferredContentSize and the modalPresentationStyle = UIModalPresentationFormSheet.
But i need my modalPresentationStyle = UIModalPresentationCustom and i can't set the frame of view controller with this presentation style.
My code is:
- (void)presentViewController:(UIViewController*)viewController withCustomSize:(NSValue*) size withInitialSetup:(void (^)(void))setupBlock withCompletion:(void (^)(void))completion {
UiViewController * navCon = [[UIViewController alloc] initWithRootViewController:viewController];
navCon.shouldDismissKeyboardOnResign = YES;
if (SYSTEM_VERSION_LESS_THAN(IOS8)){
navCon.modalPresentationStyle = UIModalPresentationFormSheet;
navCon.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
} else {
navCon.modalPresentationStyle = UIModalPresentationCustom;
navCon.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
}
[viewController setupCustomNavigationBar];
setupBlock();
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(IOS8)) {
navCon.transitioningDelegate = self;
if (size) {
CGSize sz = size.CGSizeValue;
navCon.preferredContentSize = CGSizeMake(sz.width, sz.height);
}else {
navCon.preferredContentSize = CGSizeMake(kPopupsWidth, kPopupsHeight);
}
}
[self presentViewController:navCon animated:YES completion:completion];
if (SYSTEM_VERSION_LESS_THAN(IOS8)) {
if (size) {
CGSize sz = size.CGSizeValue;
navCon.view.superview.bounds = CGRectMake(0, 0, sz.width, sz.height);
} else {
navCon.view.superview.bounds = CGRectMake(0, 0, kPopupsWidth, kPopupsHeight);
}
[navCon.view.superview.layer setCornerRadius: 8];
[navCon.view.superview.layer setBorderColor: [UIColor clearColor].CGColor];
[navCon.view.superview.layer setBorderWidth: 2];
[navCon.view.superview setClipsToBounds: YES];
}
}
I set the preferedContentSize but the frame doesn't change. Any idea why this happens?
If you're going to use UIModalPrestationCustom you have to provide a UIViewControllerTransitioningDelegate, otherwise its going to use the default transitioning delegate, which in your case sounds like a form sheet delegate.
I have a problem with memory management. A have a scrollview and every page in it loads from array of view controllers.
I load scrolview page calling the folowing method:
- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= kNumberOfPages) return;
BancaTableViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller=[[BancaTableViewController alloc] initWithPageNumber:page];
controller.banks=banks;
[controllersetDelegate:self];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
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];
}
}
This is my unload view controller method which unloads all controllers except the controller of curent page but it doesn't seem to work because the memory keep increasing.
- (void)unloadScrollViewWithPage:(int)page {
for (unsigned i = 0; i < kNumberOfPages; i++) {
if(i!=page){
[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
}
}
}
How to write the unloadviewcontroller correctly?
You're adding a hard pointer to scrollView, but you never remove the object. (i.e. you keep adding subViews to scrollView and never remove them.
[scrollView addSubview:controller.view];
Try this...
Add a tag to your controller view when you add them to the scrollView, then remove it before you load a new controller. Check syntax - from memory - not tested
if ((NSNull *)controller == [NSNull null]) {
controller=[[BancaTableViewController alloc] initWithPageNumber:page];
controller.banks=banks;
controller.tag = 3;
[controllersetDelegate:self];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
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 removeFromView:[scrollView viewWithTag:3]];
[scrollView addSubview:controller.view];
}
I'm trying to implement a Page Control to show some pages with the following storyboard:
As you can see, I've the main view with a scroll view (ViewController3) and another view (PageViewController) that represents the one that I want to push on my scroll view.
On viewDidLoad of ViewController3 I call the following method:
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= NUMBER_OF_PAGES)
return;
PageViewController *currentViewController = [viewControllers objectAtIndex:page];
if ((NSNull *)currentViewController == [NSNull null])
{
currentViewController = [[PageViewController alloc] init];
currentViewController.pageNumber = [NSString stringWithFormat:#"%d", page];
[viewControllers replaceObjectAtIndex:page withObject:currentViewController];
}
// add the controller's view to the scroll view
if (currentViewController.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
currentViewController.view.frame = frame;
currentViewController.view.backgroundColor = [UIColor yellowColor];
[self.scrollView addSubview:currentViewController.view];
self.scrollView.backgroundColor = [UIColor redColor];
NSDictionary *numberItem = [contentList objectAtIndex:page];
currentViewController.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:IMAGE_KEY]];
currentViewController.numberTitle.text = [numberItem valueForKey:NAME_KEY];
}
}
If I run the project, views with yellow background are displayed with no labels, nor image views.
As you can see, I set this background color programmatically. From my understanding, this means that the new view is correctly added to ViewController3, but it is not linked to the one configured on the storyboard.
Do you have any suggestions on how to solve this issue?
Thanks in advance,
yassa
You have to instantiate PageViewController instance using [UIStoryboard instantiateViewControllerWithIdentifier:(NSString *)identifier].
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIStoryboard_Class/Reference/Reference.html
I'm a junior and I have been really struggling to get this to work, would really appreciate some help.
I am trying to build an App where you can scroll through different WebViews by selecting an item from a table in a popover (while the popover remains in place). Unfortunately, I can't get my scrollView to move when I select an item from the popover view.
I have set up a UIScrollView with page control in a main UIViewController. The scrollView is populated with (pageViewController) UIWebViews. The main UIViewController has a nav bar with a button, when the button is clicked it creates a Popover View. When I select an item from the table in the popover view I want my UIScrollView to scroll to a certain position (equates to a selected page), but the scrollView does not move.
The method below takes the value selected from the popover and uses the page number to determine where the scrollView should scroll to, but it doesn't work because at this point my scrollView is Null.
I can supply more code if needed.
main UIViewController.m code:
- (void)setDetailItem:(id)newDetailItem {
if (detailItem != newDetailItem) {
[detailItem release];
detailItem = [newDetailItem retain];
NSString *pgnum = [[NSString alloc] initWithString:[detailItem description]];
int pg;
if(pgnum == #"Page 1"){
pg =1;
}
if(pgnum == #"Page 2"){
pg =2;
}
if(pgnum == #"Page 3"){
pg =3;
}
[pgnum release];
pageControl.currentPage = pg;
[self loadScrollViewWithPage:pg - 1];
[self loadScrollViewWithPage:pg];
[self loadScrollViewWithPage:pg + 1];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * pg;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
}
This is how I triggered the popOverController
The infoButton is on the navbar.
The scrollView is NOT NULL in the infoButton
- (void)infoButton:(id)sender {
NSLog(#"Entering: infoButton");
// [self inspectView:self.view level:#""];
if (self.popoverController == nil) {
PopoverViewController *popoverViewController =
[[PopoverViewController alloc]
initWithNibName:#"PopoverViewController"
bundle:[NSBundle mainBundle]];
popoverViewController.navigationItem.title = #"Navigation";
UINavigationController *navController =
[[UINavigationController alloc]
initWithRootViewController:popoverViewController];
UIPopoverController *popover =
[[UIPopoverController alloc]
initWithContentViewController:navController];
popover.delegate = self;
[popoverViewController release];
[navController release];
self.popoverController = popover;
[popover release];
//NSLog(#"User pressed the info button");
}
[self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; }
UIPopover, being neither the most obvious class to use memory-management wise, nor the most stable, does not require you to release it before you present it. In fact, doing so causes it to throw a fatal exception! Popovers should be released after they are removed from the screen, and/or in -dealloc.