水平UIScrollView和一堆UIButtons

时间:2013-05-26 07:50:15

标签: ios uiscrollview uibutton uipagecontrol

我需要帮助处理我要创建的应用程序,其中我有UIScrollView pages

问题在于buttons' FOO'和' BAR'在第一页中加载,而不应仅在第二页中加载。

所以,项目应该是这样的:

\--View  (The underlying UIView)
    \--scrollView (The UIScrollView)
        \--button (The buttons)

- (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;
    }
}

我有一个UIView,其中有三个水平UIScrollViews。我想要做的是,按钮将显示在第二个视图中。但每次启动应用程序时,按钮都已加载到第一个视图中,而不是第二个视图中。

__________        __________        __________
|        |        |        |        |        |
|  1st   |  <---  |  2nd   |  <---  |  3rd   |
| page   | scroll | page   | scroll | page   |
|        |        |        |        |        |
|________|        |________|        |________|

如何在第二页中加载按​​钮,并且不会再出现在第一页和第三页中?通过查看currentPage UIPageControl的{​​{1}}似乎无法正常工作。

此外,为了在我启动应用程序时首先显示第二页,需要做些什么?

1 个答案:

答案 0 :(得分:1)

这里有一些事情:

  

我有一个带有三个水平UIScrollViews的UIView

您应该只有一个 UIScrollView。它可能包含3个内容,但应该只有一个启用分页的滚动视图。

  

如何在第二个视图中加载按钮,而不是在第一个视图中?

你真的不想加载所有三页按钮吗?这样,如果用户在第2页开始并向左滚动,则第1页将加载其按钮。如果它们向右滚动,第3页将已经加载了它的按钮。

如果你真的觉得需要推迟加载下一页的按钮,直到用户开始滚动,你就可以实现UIScrollViewDelegate协议,并检测scrollViewDidScroll:中的滚动。滚动开始时,您将不得不加载新按钮。

但是,我不建议这样做。像这样按需加载可能会使你的滚动更加滞后(如果你aren't careful about performance),按钮通常不是大内存用户,所以我认为你可以随时轻松地保存所有3页按钮。

- (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;
    }
}

我认为你不想每次迭代增加xButton 200点。 SpringBoard不会像这样按下它的按钮。我曾经构建了一些模仿SpringBoard布局的东西,初始化按钮的代码是这样的:

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);

在我的代码中,我在 Touch Up Inside 事件中触发按钮点击回调,因为我认为这会带来更好的用户体验。

我还在按钮下面添加了标签 ,而不是按钮的一部分(再次模仿SpringBoard本身)。如果您愿意,可以删除该代码(btnLabel)。

  

此外,为了在启动应用程序时首先显示第二个视图,需要做些什么?

如果您有一个滚动视图,并希望从第2页开始,请使用UIPageControl中的currentPage

  - (void)viewWillAppear: (BOOL) animated {
     [super viewWillAppear: animated];
     self.pageControl.currentPage = 1;  // for page '2'
  }

注意:我似乎记得57点实际上并不是SpringBoard显示图标的大小。它的大小类似于忽略阴影/边缘效果,我认为总大小为60点。无论如何,你可以玩那个。