【问题标题】:Horizontal UIScrollView and bunch of UIButtons水平 UIScrollView 和一堆 UIButtons
【发布时间】:2013-05-26 07:50:14
【问题描述】:

我在尝试创建的应用程序方面需要帮助,其中我有一个 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   |
|        |        |        |        |        |
|________|        |________|        |________|

如何在第二页加载按钮,而不会在第一页和第三页重新出现?看来通过检查currentPageUIPageControl 是行不通的。

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

【问题讨论】:

    标签: ios uiscrollview uibutton uipagecontrol


    【解决方案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 磅。无论如何,你可以玩它。

    【讨论】:

    • 嗨。首先,我要感谢您的快速回复。其次,很抱歉造成混乱。我只有 一个 UIScrollView三个 页,就像你说的那样。第三,一、二、三页下的按钮用途和属性不同,所以加载三页下的所有按钮是不行的。
    • SpringBoard 的应用程序图标也都有不同的用途和属性(标题和图像)。为什么将所有按钮加载在一起会导致问题?
    • 谢谢!这澄清了它。
    猜你喜欢
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2018-10-26
    相关资源
    最近更新 更多