I have a UIPageViewController with a page curl (not that the transition type matters as neither works), where the second page doesn't display until the animation is finished. The code use to work, but no longer, any ideas would be great
The code is as follows:
- (void)viewDidLoad
{
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
self.pageViewController.delegate = self;
// other code deleted, for easy reading
}
- (PsalmViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.mDelegate.mPsalms count] == 0) || (index >= [self.mDelegate.mPsalms count]))
return nil;
// Create a new view controller and pass suitable data.
PsalmViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"PsalmViewController"];
PsalmData *data = [self.mDelegate.mPsalms objectAtIndex:index];
[controller setupView:index psalm:data];
self.mNextPsalm = controller;
return controller;
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if (self.mNextIndex == 0 || self.mNextIndex == NSNotFound)
return nil;
self.mNextIndex = self.mPageIndex - 1;
self.mAnimating = true;
NSLog(#"Prev %lud", (unsigned long)self.mNextIndex);
return [self viewControllerAtIndex:self.mNextIndex];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if (self.mNextIndex == NSNotFound)
return nil;
if (self.mNextIndex + 1 == [self.mDelegate.mPsalms count])
return nil;
self.mNextIndex = self.mPageIndex + 1;
self.mAnimating = true;
NSLog(#"Next %lu", (unsigned long)self.mNextIndex);
return [self viewControllerAtIndex:self.mNextIndex];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return [self.mDelegate.mPsalms count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed
{
if (completed)
{
self.mPageIndex = self.mNextIndex;
[self setCurrentPsalm:self.mNextPsalm];
}
else if (finished)
{
self.mNextIndex = self.mPageIndex;
}
if (completed || finished)
self.mAnimating = false;
NSLog(#"C %d F %d", completed, finished);
}
Again any help would be appreciated, I have no idea what is causing this problem.
Related
As my title indicated, I want to know if there's a iCarousel delegate method as well as property that I can use to set display time for each item for my banner view when auto-scroll.
Previously, I used SDCycleScrollView for my banner view and I did it this way below:
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index {
BannerData *data = self.bannerDatas[index];
NSLog(#"***************cycleScrollView************************");
NSLog(#"index --> %ld", (long)index);
NSLog(#"banner data --> %#", data);
NSLog(#"banner data duration --> %d", data.duration);
cycleScrollView.autoScrollTimeInterval = data.duration;
}
data.duration is duration for each item to stay still.
How can I achieve this with iCarousel? Thanks in advance.
Here below are my iCarousel methods so far:
- (NSInteger)numberOfItemsInCarousel:(__unused iCarousel *)carousel
{
NSLog(#">>>>>>>>>number of items in Carousel --> %lu", (unsigned long)[self.bannerDatas count]);
return (NSInteger)[self.bannerDatas count];
}
- (UIView *)carousel:(__unused iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{
view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 520, 375)];
NSLog(#"url --> %#", [NSURL URLWithString:[self.netImages objectAtIndex:index]]);
[((UIImageView *)view)sd_setImageWithURL:[NSURL URLWithString:[self.netImages objectAtIndex:index]] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
view.contentMode = UIViewContentModeCenter;
return view;
}
- (void)scrollToItemAtIndex:(NSInteger)index duration:(NSTimeInterval)duration
{
BannerData *data = self.bannerDatas[index];
NSLog(#"***************cycleScrollView************************");
NSLog(#"index --> %ld", (long)index);
NSLog(#"banner data --> %#", data);
NSLog(#"banner data duration --> %d", data.duration);
}
- (CGFloat)carousel:(__unused iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
{
//customize carousel display
switch (option)
{
case iCarouselOptionWrap:
{
//normally you would hard-code this to YES or NO
return YES;
}
case iCarouselOptionSpacing:
{
//add a bit of spacing between the item views
//return value * 1.05;
}
case iCarouselOptionFadeMax:
{
// if (self.carousel.type == iCarouselTypeCustom)
// {
// //set opacity based on distance from camera
// return 0.0;
// }
// return value;
}
case iCarouselOptionShowBackfaces:
case iCarouselOptionRadius:
case iCarouselOptionAngle:
case iCarouselOptionArc:
case iCarouselOptionTilt:
case iCarouselOptionCount:
case iCarouselOptionFadeMin:
case iCarouselOptionFadeMinAlpha:
case iCarouselOptionFadeRange:
case iCarouselOptionOffsetMultiplier:
case iCarouselOptionVisibleItems:
{
return value;
}
}
}
#pragma mark -
#pragma mark iCarousel taps
- (void)carousel:(__unused iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
{
BannerData *data = self.bannerDatas[index];
if (![data.playlistId isEqualToString:#""]) { //Play Playlist
CategoryDetailData *detailData = [[CategoryDetailData alloc]init];
detailData.categoryId = data.playlistId;
RandomSecondVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"RandomSecondVC"];
vc.detailData = detailData;
NSLog(#"vc.detailData.categoryId --> %#", vc.detailData.categoryId );
vc.hidesBottomBarWhenPushed = YES; //????sanit
[self.navigationController pushViewController:vc animated:YES];
} else if (![data.url isEqualToString:#""]) { //Show webview
WebViewVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"WebViewVC"];
vc.hidesBottomBarWhenPushed = YES;
vc.navTitle = #"";
vc.urlString = data.url;
[self.navigationController pushViewController:vc animated:YES];
}else if (![data.videoId isEqualToString:#""]) { //Play video
VideoDetailVC *detailView = [self.storyboard instantiateViewControllerWithIdentifier:#"VideoDetailVC"];
detailView.videoId = data.videoId;
detailView.hidesBottomBarWhenPushed = YES; //????sanit
[self.navigationController pushViewController:detailView animated:YES];
}
}
Here below is how I place my Carousel view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *tableCell = nil;
if (indexPath.section == 0) { //for banner
//++++++++++++++++++++??sanit iCarousel ver.1++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
NSLog(#"first section!!!!!!!!");
static NSString *BannerCellIdentifier = #"BannerTableViewCell"; //original
BannerTableViewCell *bannerCell = [tableView dequeueReusableCellWithIdentifier:BannerCellIdentifier]; //original
//BannerTableViewCell *bannerCell = [[BannerTableViewCell alloc]init];
[self setUpNetImages];
bannerCell.carouselView.type = iCarouselTypeCoverFlow2;
//bannerCell.carouselView.type = iCarouselTypeLinear;
//bannerCell.carouselView.autoscroll = 1; //?????sanit set autoscroll
bannerCell.carouselView.delegate = self;
bannerCell.carouselView.dataSource =self;
//??????sanit to fix banner timing issue first banner
//BannerData *data0 = self.bannerDatas[1]; //???santi
//self.cycleScrollView.autoScrollTimeInterval = data0.duration; // use this to fix timing issue of first slide
//[bannerCell.carouselView scrollToItemAtIndex:0 duration:data0.duration];
//bannerCell.carouselView.autoscroll = 0.8;
//[bannerCell.carouselView scrollToItemAtIndex:0 duration:5];
//[bannerCell.carouselView scrollToItemAtIndex:1 animated:YES];
[bannerCell.carouselView reloadData];
tableCell = bannerCell;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=//
} else { //for collection cell below
NSLog(#"not first section!!!!!!!! %d",(int)indexPath.section);
static NSString *MainHeaderCellIdentifier = #"MainHeaderTableViewCell";
MainHeaderTableViewCell *mainHeaderCell = (MainHeaderTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MainHeaderCellIdentifier]; //original
mainHeaderCell.collectionView = (UICollectionView *)[mainHeaderCell viewWithTag:100];
mainHeaderCell.collectionView.delegate = self;
mainHeaderCell.collectionView.dataSource = self;
//NSLog(#"mainHeaderCell.index = %d",(int)mainHeaderCell.index);
//original
if (mainHeaderCell.collectionView == nil) {
NSLog(#"CollectionView Nil!!!!!!!");
}
tableCell = mainHeaderCell;
}
return tableCell;
}
Seems that iCarousel does not have that option, but, luckily, you can implement such functionality by yourself:
#property (nonatomic, strong) NSMutableDictionary *operations;
#property (nonatomic) BOOL isDragging;
- (void) carouselDidEndScrollingAnimation:(iCarousel *)carousel
{
if (!self.isDragging){
NSNumber *tag = #(carousel.tag);
[self.operations[tag] cancel];
self.operations[tag] = [NSBlockOperation blockOperationWithBlock:^{
double duration = [self durationForItemAtIndex:carousel.currentItemIndex inCarousel:carousel];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSInteger i = carousel.currentItemIndex + 1;
NSInteger next = i < carousel.numberOfItems ? i : 0;
[carousel scrollToItemAtIndex:next animated:YES];
});
}];
[(NSOperation*)(self.operations[tag]) start];
}
}
- (void) carouselWillBeginDragging:(iCarousel *)carousel
{
[self.operations[#(carousel.tag)] cancel];
self.isDragging = YES;
}
- (void) carouselDidEndDragging:(iCarousel *)carousel willDecelerate: (BOOL)decelerate
{
self.isDragging = NO;
}
- (double) durationForItemAtIndex:(NSInteger)index inCarousel:(iCarousel*)carousel
{
return <appropriate_duration_for_particular_carousel_and_item_index_in_it>;
}
- (void) startCarousel:(iCarousel*)carousel
{
[self carouselDidEndScrollingAnimation:carousel];
}
Update -[tableView:cellForRowAtIndexPath:] method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
<...>
if (indexPath.section == 0) {
<...>
bannerCell.carouselView.tag = indexPath.row;
[self startCarousel:bannerCell.carouselView];
} else {
<...>
}
return tableCell;
}
And don't forget to initialize the operations dictionary somewhere before usage:
self.operations = [NSMutableDictionary new];
However, all this is kind of draft - you may want to tune and upgrade these snippets according to your needs.
I have a UIPageViewController in a UIViewController , I am having a problem where the pageviewcontroller's inner view are not shown [Although I am sure they are loaded from the server]!
Some helpful notes:
UIPageViewController (called :pageController)
Outer UIViewController (called :OfferDetailsViewController)
each viewController inside the pageController is of type OfferBannerPageViewController
Here is my code related to the problem , Please ask for any other blocks of code if you think it will help finding the problem source
some of :OfferDetailsViewController.m :
- (void)viewDidLoad {
[super viewDidLoad];
delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
if(_offerId)
{
_offer = [[Offer alloc]init];
[delegate setUpAConnectionToGetADetailedOffer:_offerId];
//first: load the offer
[self loadOffer];
[self startTimer];
}
}
-(void) loadOffer{
NSMutableString * pathPattern = [NSMutableString stringWithString: #"api/Offers/"];
[pathPattern appendString:_offerId];
[[RKObjectManager sharedManager]getObjectsAtPath:pathPattern parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
if(mappingResult){
_offer = (Offer *)[mappingResult.array firstObject];
//second load the offer banners images
[self setOfferView];
dispatch_async(dispatch_get_main_queue(), ^{
[self loadOfferBanners];
});
}else{
}
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
}];
}
-(void)loadOfferBanners {
_offer.OfferPannerImagesObjects = [[NSMutableArray alloc]init];
for(int index = 0 ; index<_offer.OfferPannerImages.count ;index++){
NSURL *imageURL =[NSURL URLWithString:_offer.OfferPannerImages[index]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
//[UIImage imageWithData:imageData];
if(image){
[_offer.OfferPannerImagesObjects addObject: image];
}
}
if(_offer.OfferPannerImagesObjects.count>0){
[self setUpOfferBanners];
}
}
-(void)setUpOfferBanners {
self.pageController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.dataSource = self;
CGRect rect = [self.pagesView bounds];
[[self.pageController view] setFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)];
OfferBannerPageViewController * initialBanner = [self viewControllerAtIndex: 0];
[self.pageController setViewControllers:[NSArray arrayWithObjects:initialBanner, nil] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil ];
[self addChildViewController:self.pageController];
[[self pagesView] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
self.pagesView.clipsToBounds=YES;
self.pagesView.layer.cornerRadius= 6;
}
here is the ViewControllerAtIndex method I debug it and found that index is always whereas when I hover in it after stopping at a break point I see its value as 0!
- (OfferBannerPageViewController *)viewControllerAtIndex:(NSUInteger)index {
OfferBannerPageViewController *offerBannerPageViewController = [[OfferBannerPageViewController alloc] initWithNibName:#"OfferBannerPageViewController" bundle:nil];
offerBannerPageViewController.bannerView = _offer.OfferPannerImagesObjects[index];
offerBannerPageViewController.index = [NSNumber numberWithLong:(long)index];
NSLog(#"____________________ [INDEX = %ld] ___________________",(long)index);
[offerBannerPageViewController.bannerView setImage:_offer.OfferPannerImagesObjects[index]];
return offerBannerPageViewController;
}
any help will be extremely appreciated, Thank you.
update
- (NSInteger)presentationCountForPageViewController: (UIPageViewController*)pageViewController {
// The number of items reflected in the page indicator.
return [_offer.OfferPannerImages count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
NSInteger index = (long)((OfferBannerPageViewController *)viewController).index;
if(index >= _offer.OfferPannerImagesObjects.count){
return nil;
}
index ++;
return [self viewControllerAtIndex:index];
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSInteger index = (long)((OfferBannerPageViewController *)viewController).index;
if(index == 0)
return nil;
index--;
return [self viewControllerAtIndex:index];
}
update 2: OfferBannerPageViewController.h
#interface OfferBannerPageViewController : UIViewController
#property (strong,nonatomic) NSNumber * index;
#property (strong,nonatomic)IBOutlet UIImageView * bannerView;
#end
Not sure about this, but maybe you should use autoresizing masks to make sure OfferBannerPageViewController's view resizes width and height along with the superview. It might happen that when you set the frame of pageController.view based on bounds of superview, the bounds are 0 width and height and then doesn't resize.
So try:
[[self.pageController view] setFrame:CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)];
[[self.pageController view] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
Have you implemented presentationCountForPageViewController, presentationIndexForPageViewController, viewControllerBeforeViewController and viewControllerAfterViewController methods?
Please, show them.
Need some help with a complex issue on my paginated scrollview. Im adding multiple pages with tableviews and some more data that could be heavy for memory. But it building up memory with each scroll. I would like my code to only add a subview once and on scroll replace it and release the old on (im using ARC). But the memory is building up, i think its because its adding the subview multiple times.
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
#synchronized(self) {
#autoreleasepool {
CGFloat pageWidth = mainScrollView.frame.size.width;
NSInteger page = round(mainScrollView.contentOffset.x / pageWidth);
int scrollOffset = (page * barWidth)-(mainScrollView.bounds.size.width/2);
if (scrollOffset<=0) {
scrollOffset = 0;
} else if (scrollOffset >= (pageIndicatorScrollView.contentSize.width - pageIndicatorScrollView.frame.size.width)) {
scrollOffset = (pageIndicatorScrollView.contentSize.width - pageIndicatorScrollView.frame.size.width);
}
[pageIndicatorScrollView setContentOffset:CGPointMake(scrollOffset, 0) animated:YES];
if(page < 0)
{
page = 0;
}
if(page >= [categoryScrollersArray count])
{
page = [categoryScrollersArray count] - 1;
}
//page = page +1;
//////////NSLog(#"page = %d",page);
// don't create or delete pages while rotating
if (!isRotating) {
if([categoryScrollersArray count] == 1)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
}
else if([categoryScrollersArray count] == 2)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
if([categoryScrollersArray objectAtIndex:1] == [NSNull null])
{
[self loadScrollViewWithPage:1];
}
}
else
{
if(page - 1 < 0)
{
if([categoryScrollersArray objectAtIndex:0] == [NSNull null])
{
[self loadScrollViewWithPage:0];
}
if([categoryScrollersArray objectAtIndex:1] == [NSNull null])
{
[self loadScrollViewWithPage:1];
}
}
else
{
if([categoryScrollersArray objectAtIndex:page - 1] == [NSNull null])
{
[self loadScrollViewWithPage:page - 1];
}
if([categoryScrollersArray objectAtIndex:page] == [NSNull null])
{
[self loadScrollViewWithPage:page];
}
if(page + 1 < [categoryScrollersArray count])
{
if([categoryScrollersArray objectAtIndex:page + 1] == [NSNull null])
{
[self loadScrollViewWithPage:page + 1];
}
}
}
if(page -2 >= 0 )
{
if([categoryScrollersArray objectAtIndex:page -2] != [NSNull null])
{
UIView *u = [categoryScrollersArray objectAtIndex:page-2];
//////////NSLog(#"remove page = %d",page-2);
[u removeFromSuperview];
if (page-2 < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page-2] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1307)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page-2 withObject:[NSNull null]];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1314)"];
}
}
}
if(page +2 < [categoryScrollersArray count])
{
if([categoryScrollersArray objectAtIndex:page +2] != [NSNull null])
{
UIView *u = [categoryScrollersArray objectAtIndex:page+2];
// [u removeObserver:u.self forKeyPath:#"doReload"];
//////////NSLog(#"remove page = %d",page+2);
[u removeFromSuperview];
if (page+2 < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page+2] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1329)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page+2 withObject:[NSNull null]];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1337)"];
}
}
}
}
}
[self changeProgressBar:page];
// ////////NSLog(#"viewControllers are %#",viewControllers);
// ////////NSLog(#"questionsScroll.subviews %#",questionsScroll.subviews);
}
}
}
And the other function:
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= [categoryScrollersArray count])
return;
//Categories * anCat;
//anCat = [catArray objectAtIndex:page];
// replace the placeholder if necessary
CategoryScrollerView *catScroll = [categoryScrollersArray objectAtIndex:page];
if ((NSNull *)catScroll == [NSNull null])
{
Step *aStep = [steps objectAtIndex:page];
NSString *coder = [[NSString alloc] init];
if ([self.visit.savedStatus integerValue] == 2 && [self.visit.state integerValue] == 1) {
coder = #"SAVED";
} else {
coder = #"OPEN";
}
NSString *questCode = [NSString stringWithFormat:#"%#",self.visit.questionnaire.version];
catScroll = [[CategoryScrollerView alloc] initWithFrame:mainScrollView.frame andStep:aStep andDelegate:self andStepname:aStep.name andVisitcode:coder andQuestionnairecode:questCode];
catScroll.autoresizesSubviews = YES;
catScroll.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
[self setNextBtnTitleForPage:page andView:catScroll];
if (page < [categoryScrollersArray count]) {
if ([categoryScrollersArray objectAtIndex:page] == nil) {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1101)"];
}
else {
[categoryScrollersArray replaceObjectAtIndex:page withObject:catScroll];
}
}
else {
[self showUnexpectedBehaviorAlertWithTest:#"An unknown error occured, please reopen the questionnaire. (1108)"];
}
}
// add the controller's view to the scroll view
if (catScroll.superview == nil)
{
CGRect frame = mainScrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
catScroll.frame = frame;
[mainScrollView addSubview:catScroll];
// NSDictionary *numberItem = [self.contentList objectAtIndex:page];
// controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]];
// controller.numberTitle.text = [numberItem valueForKey:NameKey];
}
}
Doing this inside one view controller is going to be really complex. Especially if you're trying to do all the tableview datasource stuff in there too.
You would be much better off using a UIPageViewController.
It is a container controller (a lot like UINavigationController or UITabBarController) that is used to display view controllers in a paged scroll view type of view.
There are some tutorials here about using UIPageViewController. http://www.raywenderlich.com/?s=uipageviewcontroller&cof=FORID%3A10
Essentially you pass a different table view controller in for each page. It takes a bit of settings up but once it's done it will help make it much easier and will keep memory usage down.
There are lots more tutorials out there too... http://www.appcoda.com/uipageviewcontroller-tutorial-intro/
Also, you don't have to make it full screen. You can use the Page View Controller for only the part of the screen that you want to scroll.
I want to print a list of all of the app's viewcontrollers which are loaded in order to understand why am I getting a white screen and for general debugging purposes.
Please advise,
Thanks,
Asaf
You can do some recursive printout like this (I know it's not perfect, but it's a start):
static void printViewControllerRecursively(UIViewController *viewController, NSUInteger level)
{
NSMutableString *spaces = [NSMutableString stringWithCapacity:level * 3];
for (NSUInteger i = 0; i < level; ++i)
{
[spaces appendString:#" "];
}
NSLog(#"%#->%#", spaces, viewController);
if ([viewController isKindOfClass:[UITabBarController class]])
{
for (UIViewController *child in [(UITabBarController *)viewController viewControllers])
{
printViewControllerRecursively(child, level + 1);
}
}
else if ([viewController isKindOfClass:[UINavigationController class]])
{
for (UIViewController *child in [(UINavigationController *)viewController viewControllers])
{
printViewControllerRecursively(child, ++level);
}
}
}
Then just call printViewControllerRecursively([UIApplication sharedApplication].keyWindow.rootViewController, 0);
This doesn't seem like a good way to try and debug anyhitng but that being said you can use:
NSLog(#"%#", [self.navigationController viewControllers]);
or
NSLog(#"%#", [self.tabBarController viewControllers]);
etc ...
Guess it depends on how you've setup your App.
Have been working on single view game, which includes targetValue and score, both of which should appear in the outlets in the view. Connected them to the view controller (File's Owner) in IB, and the targetValue used to appear, but now, after adding some code, it doesn't appear anymore.
What's wrong?
Here is the code from BullseyeViewController.m:
#import "BullsEyeViewController.h"
#implementation BullsEyeViewController {
int currentValue;
int targetValue;
int score;
}
#synthesize slider;
#synthesize targetLabel;
#synthesize scoreLabel;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)updateLabels
{
self.targetLabel.text = [NSString stringWithFormat:#"%d", targetValue];
self.scoreLabel.text = [NSString stringWithFormat:#"%d",score];
}
- (void)startNewRound
{
targetValue = 1 + (arc4random() % 100);
currentValue = self.slider.value;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self startNewRound];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.slider = nil;
self.targetLabel = nil;
self.scoreLabel = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
- (IBAction)showAlert
{
int difference = abs(targetValue - currentValue);
int points = 100 - difference;
score += points;
NSString *title;
if (difference == 0) {
title = #"Perfect!";
points += 100;
} else if (difference < 5) {
if (difference == 1) {
points += 50;
}
title = #"You almost had it!";
} else if (difference < 10) {
title = #"Pretty good!";
} else {
title = #"Not even close...";
}
NSString *message = [NSString stringWithFormat:#"You scored %d points", points];
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:title
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
}
- (IBAction)sliderMoved:(UISlider *)slider
{
currentValue = lroundf(slider.value);
}
#end
if you set a breakpoint on updateLabels, does it ever hit?
Also, change your updateLabels method to look like this:
- (void)updateLabels
{
targetLabel.text = [NSString stringWithFormat:#"%d", targetValue];
scoreLabel.text = [NSString stringWithFormat:#"%d",score];
}
Do you refer to these labels from outside of your view controller? If not, do they need to be properties?