I got this code from the apple sample project scrolling:
@synthesize scrollView1, scrollView2;
const CGFloat kScrollObjHeight = 467.0;
const CGFloat kScrollObjWidth = 320.0;
const NSUInteger kNumImages = 6;
- (void)layoutScrollImages
{
UIImageView *view = nil;
NSArray *subviews = [scrollView1 subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews)
{
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];
}
I tried to modify this to load subviews instead of images but it doesnt work. I think I’m somehow replacing the views instead of adding them? I need to load the views from separate xib files, and scroll left to right through the xib’s (they each contain a panel of buttons leading to different levels in my game). So what am I doing wrong? Why doesnt this work? It only ever shows the second panel and whenever i push a button it crashes with a SIGABRT.
#import "LevelSelectButtons.h"
@implementation LevelSelectButtons
@synthesize levelScroll;
const int kScrollObjHeight = 400;
const int kScrollObjWidth = 320;
const NSUInteger kNumCategories = 5;
- (void)layoutScrollScreens {
UIImageView *view = nil;
NSArray *subviews = [levelScroll subviews];
// reposition all image subviews in a horizontal serial fashion
CGFloat curXLoc = 0;
for (view in subviews) {
if ([view isKindOfClass:[UIImageView class]] && view.tag > 0) {
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc, 0);
view.frame = frame;
curXLoc += (kScrollObjWidth);
}
}
// set the content size so it can be scrollable
[levelScroll setContentSize:CGSizeMake((kNumCategories * kScrollObjWidth), [levelScroll bounds].size.height)];
}
- (void)viewDidLoad {
[levelScroll setScrollEnabled:YES];
CGFloat width = 640; //kScrollObjWidth*kNumCategories;
CGFloat height = 400;
[levelScroll setContentSize:CGSizeMake(width, height)];
[self.view addSubview:levelScroll];
levelScroll.pagingEnabled = YES;
levelScroll.indicatorStyle = UIScrollViewIndicatorStyleWhite;
levelScroll.pagingEnabled = YES;
/// LEVELS 1 ///
NSUInteger viewNum = 0;
CGRect catViewFrame = CGRectMake(0, 0, kScrollObjWidth, kScrollObjHeight);
UIView *levels1view = [[UIView alloc] initWithFrame:catViewFrame];
NSArray *array1 = [[NSBundle mainBundle] loadNibNamed:@"Levels1" owner:self options:nil];
levels1view = [array1 objectAtIndex:0];
levels1view.tag = viewNum;
[self.levelScroll addSubview:levels1view];
/// LEVELS 2 ///
viewNum = 1;
catViewFrame = CGRectMake(320, 0, kScrollObjWidth, kScrollObjHeight);
UIView *levels2view = [[UIView alloc] initWithFrame:catViewFrame];
NSArray * array2= [[NSBundle mainBundle] loadNibNamed:@"Levels2" owner:self options:nil];
levels2view = [array2 objectAtIndex:0];
levels2view.tag = viewNum;
[self.levelScroll addSubview:levels2view];
[self layoutScrollScreens];
[super viewDidLoad];
}
This is the line where the SIGABRT appears:
int retVal = UIApplicationMain(argc, argv, nil, nil);
This is to explain why only
levels2viewis shown.If you look here, you’re creating a new view with the desired frame where you want your
levels2viewto be positioned. But,Here you’re reassigning the variable to a new view and thus losing the reference to the view you created resulting in a memory leak. That aside, this view doesn’t have its frame set. This will default to origin being at
CGPointZero. And since you do the same thing withlevels1view, you end up positioninglevels2viewon top oflevels1viewwhen you add them to the scroll view when you add them in that order.To remedy this,