Reputation: 668
I need help with the application I am trying to create, in which I have a UIScrollView
and three pages
.
The problem is that buttons
'FOO' and 'BAR' are loaded in the first page, instead it should be loaded in the second page only.
So, the project should be like this:
\--View (The underlying UIView) \--scrollView (The UIScrollView) \--button (The buttons)
and
- (void)createButton
{
float xButton = 10.0;
NSArray *buttonTitles = @[@"foo", @"bar"];
for (int i = 0; i < 2; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(xButton, 10.0, 100.0, 50.0);
[button setTitle:buttonTitles[i] forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];
[scrollView addSubview:button];
[button setTag:i];
xButton += 200;
}
}
I have a UIView
with three horizontal UIScrollViews
. What I want to do is, the buttons are to be displayed in the second view. But every time I launch the application, the buttons are already loaded in the first view, and not in the second view.
__________ __________ __________
| | | | | |
| 1st | <--- | 2nd | <--- | 3rd |
| page | scroll | page | scroll | page |
| | | | | |
|________| |________| |________|
How will I load the buttons in the second page, and won't reappear in the first and third page? It seems that by checking the currentPage
of UIPageControl
won't work.
In addition, what are needed to be done in order for my second page to be displayed first whenever I launch the application?
Upvotes: 1
Views: 1020
Reputation: 31045
A few things here:
I have a UIView with three horizontal UIScrollViews
You should only have one UIScrollView
. It may have 3 pages of content, but there should only be one, paging-enabled scroll view.
How will I load the buttons in the second view, and not in the first view?
Don't you really want to load all three pages of buttons? That way, if the user starts on page 2 and scrolls left, page 1 will have its buttons loaded. If they scroll right, page 3 will already have its buttons loaded.
If you really, really feel you need to defer loading of the next page's buttons until the user starts scrolling, you could implement the UIScrollViewDelegate
protocol, and detect scrolling in scrollViewDidScroll:
. When the scroll starts, you're then going to have to load new buttons.
But, I wouldn't recommend this. Loading on demand like this may make your scrolling more laggy (if you aren't careful about performance), and buttons normally aren't big memory users, so I would think that you could easily keep all 3 pages of buttons loaded at all times.
- (void)createButton
{
float xButton = 10.0;
NSArray *buttonTitles = @[@"foo", @"bar"];
for (int i = 0; i < 2; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(xButton, 10.0, 100.0, 50.0);
/* button setup here */
xButton += 200;
}
}
I don't think you want to increment xButton
by 200 points every iteration. SpringBoard doesn't space its buttons like that. I once built something that sort of imitated SpringBoard's layout, and the code to initialize the buttons was something like this:
const int PADDING = 4;
const int SCREEN_WIDTH = 320;
const int SCREEN_HEIGHT = 411;
const int SPACING = (SCREEN_WIDTH - (4 * 57)) / 5; // 5 spaces between 4 columns
float x = SPACING;
float y = SPACING;
int index = 0;
int page = 0;
for (NSString* title in buttonTitles) {
UILabel* btnLabel = [[UILabel alloc] initWithFrame: CGRectMake(x, y + 57 + PADDING, 57, 20)];
btnLabel.text = title;
btnLabel.font = [UIFont boldSystemFontOfSize: 12.0];
btnLabel.shadowColor = [UIColor darkGrayColor];
btnLabel.shadowOffset = CGSizeMake(1, 1);
btnLabel.textColor = [UIColor whiteColor];
btnLabel.opaque = NO;
btnLabel.backgroundColor = [UIColor clearColor];
btnLabel.textAlignment = UITextAlignmentCenter;
[self.scrollView addSubview: btnLabel];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(x, y, 57, 57);
// NOTE: my code uses labels beneath buttons, not button titles
//[button setTitle:title forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:button];
// index tag helps us determine which button was pressed later
[button setTag:index];
// I keep a NSMutableSet of all the buttons
[self.buttons addObject: button];
if ((x + (2 * 57) + SPACING) > (SCREEN_WIDTH * (page + 1))) {
// new row
x = SCREEN_WIDTH * page + SPACING;
if ((y + (2 * 57) + SPACING) > SCREEN_HEIGHT) {
// new page (to the right of the last one)
page++;
y = SPACING;
x = SCREEN_WIDTH * page + SPACING;
} else {
y += 57 + PADDING + 20 + SPACING;
}
} else {
x += 57 + SPACING;
}
index++;
}
// set the virtual scrollView size to allow paging/scrolling horizontally
self.scrollView.contentSize = CGSizeMake(SCREEN_WIDTH * (page + 1), SCREEN_HEIGHT);
In my code, I trigger the button click callback on the Touch Up Inside event, as I think that makes for a better user experience.
I also added labels below my buttons, not as part of the buttons (again, imitating SpringBoard itself). You can delete that code (btnLabel
) if you like.
In addition, what are needed to be done in order for my second view to be displayed first whenever I launch the application?
If you have one scroll view, and want to start on page 2, use currentPage from your UIPageControl
:
- (void)viewWillAppear: (BOOL) animated {
[super viewWillAppear: animated];
self.pageControl.currentPage = 1; // for page '2'
}
Note: I seem to remember that 57 points isn't actually the size SpringBoard displays icons at. It's something like the size, ignoring the shadow/edge effects, which I think brings the total size to 60 points. Anyway, you can play with that.
Upvotes: 1