iOS—;粘性分段控件,如应用商店应用程序

iOS—;粘性分段控件,如应用商店应用程序,ios,objective-c,Ios,Objective C,我正在创建一个应用程序,在其中一个导航视图中,我的设计与app Store应用程序的设计非常相似-请参阅详细信息|评论|相关部分。接下来,我希望以苹果在其应用程序中所做的“相同”方式实现分段控制。(这也类似于苹果在默认iOS 7音乐应用程序的“艺术家->专辑导航”视图中所做的操作,尽管是针对表格标题(可能) 如果向上滚动,当分段控件容器接触到导航栏时,它会粘在那里 它还允许用户注意到,由于与它相关联的alpha,这是某种覆盖 向下滚动时,它会在需要时移动到位 我所做的- 我已经用分段控件创建

我正在创建一个应用程序,在其中一个导航视图中,我的设计与app Store应用程序的设计非常相似-请参阅详细信息|评论|相关部分。接下来,我希望以苹果在其应用程序中所做的“相同”方式实现分段控制。(这也类似于苹果在默认iOS 7音乐应用程序的“艺术家->专辑导航”视图中所做的操作,尽管是针对表格标题(可能)

  • 如果向上滚动,当分段控件容器接触到导航栏时,它会粘在那里
  • 它还允许用户注意到,由于与它相关联的alpha,这是某种覆盖
  • 向下滚动时,它会在需要时移动到位
我所做的-

我已经用分段控件创建了一个容器视图。当scrollView滚动时,我重新定位容器视图以实现粘性效果。这只是伪代码,但我的代码实际上可以工作

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView == self.labTestScrollView)
    {
        /*
         As soon as the user scrolls up, y changes, therefore, we need to stick the options container view
         such that it doesn't go past the UINavigationBar
         Need to check if the origin of the options container view in the coordinate system of the main
         superview is just gone past the UINavigationBar in this controller's view.
         - get the bounds rect for the options container view
         - convert these bounds and position them in the coordinates of this controller's view
         - check if origin.x for container view is less than that of view.origin.y
         - if less than stick it by converting the headerFrame to the coordinate system of the options 
         container view; and raise the stuck flag
         - if greater, check if the stuck flag is raised; check for another object in space before the container view and adjust accordingly.
         */
    }
}
有两个问题:

  • 没有叠加效果。我可以对alpha进行配置,使效果更加明显,但这似乎并不自然
  • 第二个担忧源于第一个担忧。这似乎是一个非常具体的解决方案。我期待着更自然的东西;还有一些默认情况下可以使用表视图之类的东西

  • 为什么不直接使用
    UITableView

    将您的“顶级内容”放在第0节中,并且没有该节的标题。将所有其他内容放在第1节中,并使用
    UISegmentedControl
    为该节提供一个标题

    下面的代码工作得很好。你可能想找到一种方法,给标题的背景一个“模糊”效果,以模仿苹果的行为更多;也许我能帮你

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 2;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return section == 0 ? 1 : 5;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSString *identifier = indexPath.section == 0 ? @"header" : @"content";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
        // customize cell
        return cell;
    }
    
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        if(section == 1) {
            UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Foo", @"Bar"]];
            segmentedControl.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.95];
            return segmentedControl;
        }
        return nil;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
        return section == 0 ? 0 : 44;
    }
    

    我将把调整留给你;)

    这实际上是两个视图

    第一个是UITableView的标题

    这包括分段控件和应用程序图标、安装按钮等

    第二个视图有一个分段控件,该控件位于屏幕顶部并隐藏

    当tableview滚动时,您可以截取scroll view委托方法scrollView:didScroll

    在这里,如果scrollView偏移大于标题的高度,则使第二个视图可见。否则就把它藏起来


    就这样。现在,您只需要记住,每当一个分段控件被挂起时,都要更新这两个分段控件。

    好的,这种方法很有意义。关于App Store应用程序,图标、应用程序名称等位于第0部分,并且没有任何标题。
    UISegmentedControl
    之后的所有内容都在第1节中,
    UISegmentedControl
    是本节的标题。这就是你说的吗?好的,这很好。我知道你做了什么。这正是我想要的。非常感谢!:)这仅在所有tableview内容(除标题外)都放在一个部分时有效。只需稍作调整,我将在viewDidLoad中分配并初始化“segmentedControl”。。。然后返回viewForHeaderInSection方法。这样,它只加载一次并重新使用,而不是在每次刷新表时分配。我理解。是否有一些测试代码可以实现您刚才描述的功能?另外,你确定这是应用商店应用程序中的实际实现吗?除了苹果开发者之外,没有人会确切知道它是什么。我过去也做过类似的事情。然而,我也喜欢fguchelaar的解决方案。在现实中,实际的实现可能不是上述两种情况。谢谢你的意见。