Iphone 分区左侧的UITableView标题(如聚光灯)

Iphone 分区左侧的UITableView标题(如聚光灯),iphone,ios,cocoa-touch,uitableview,Iphone,Ios,Cocoa Touch,Uitableview,我已经找了很长一段时间了,但我仍然没有找到一个方法来做这件事。 我想将iPhone Spotlight的部分标题复制到UITableView中 众所周知,当您滚动时,“常规”表视图标题在部分顶部保持可见。但是有一种标题,我在其他地方从未见过,除了在Springboard的聚光灯页面上:在那里,标题跨越了该部分的整个高度,并没有固定在该部分的顶部,而是在左侧 这到底是怎么做到的?好问题。我做了一个小实验。它看起来就像聚光灯下的景色。但它缺少一个重要特性。下部“图像”在碰撞时不会将上部图像推到顶部

我已经找了很长一段时间了,但我仍然没有找到一个方法来做这件事。 我想将iPhone Spotlight的部分标题复制到UITableView中

众所周知,当您滚动时,“常规”表视图标题在部分顶部保持可见。但是有一种标题,我在其他地方从未见过,除了在Springboard的聚光灯页面上:在那里,标题跨越了该部分的整个高度,并没有固定在该部分的顶部,而是在左侧


这到底是怎么做到的?

好问题。我做了一个小实验。它看起来就像聚光灯下的景色。但它缺少一个重要特性。下部“图像”在碰撞时不会将上部图像推到顶部

我怀疑是否存在不使用私有框架的内置解决方案


我做到了这一点:

正如您所见,顶部的两个标题图像重叠。他们不像正常的头那样互相推压。我不得不关闭细胞分离器。如果我使用它们,它们会出现在整个牢房里。所以你必须自己画。没什么大不了的

但我不知道如何修复重叠

以下是实现这一点的代码:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 1;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];
    contentView.backgroundColor = [UIColor lightGrayColor];

    UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 34, 34)] autorelease];
    imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d", section]];;

    [contentView addSubview:imageView];
    return [contentView autorelease];
}
好消息:参见


好的,我做了一些类似于音乐应用和聚光灯搜索的事情

我没有将UITableView子类化,我只是通过它的scrollViewDidScroll方法跟踪了各个部分,并将标题视图添加到tableView的左侧(因此您必须将tableView放在viewController视图的右侧,这意味着您不能使用UITableViewController)

应该在scrollViewDidScroll、ViewDidLoad和didRotateFromInterfaceOrientation中调用此方法:(如果支持旋转)

请记住,您必须使左侧的空间等于您支持的任何接口方向的标题大小

-(void)updateHeadersLocation
{
for (int sectionNumber = 0; sectionNumber != [self numberOfSectionsInTableView:self.tableView]; sectionNumber++)
{
    // get the rect of the section from the tableview, and convert it to it's superview's coordinates
    CGRect rect = [self.tableView convertRect:[self.tableView rectForSection:sectionNumber] toView:[self.tableView superview]];

    // get the intersection between the section's rect and the view's rect, this will help in knowing what portion of the section is showing
    CGRect intersection = CGRectIntersection(rect, self.tableView.frame);

    CGRect viewFrame = CGRectZero; // we will start off with zero

    viewFrame.size = [self headerSize]; // let's set the size

    viewFrame.origin.x = [self headerXOrigin];

    /*

     three cases:

     1. the section's origin is still showing -> header view will follow the origin
     2. the section's origin isn't showing but some part of the section still shows -> header view will stick to the top
     3. the part of the section that's showing is not sufficient for the view's height -> will move the header view up

     */

    if (rect.origin.y >= self.tableView.frame.origin.y)
    {
        // case 1
        viewFrame.origin.y = rect.origin.y;
    }
    else
    {
        if (intersection.size.height >= viewFrame.size.height)
        {
            // case 2
            viewFrame.origin.y = self.tableView.frame.origin.y;
        }
        else
        {
            // case 3
            viewFrame.origin.y = self.tableView.frame.origin.y + intersection.size.height - viewFrame.size.height;
        }
    }

    UIView* view = [self.headerViewsDictionary objectForKey:[NSString stringWithFormat:@"%i", sectionNumber]];

    // check if the header view is needed
    if (intersection.size.height == 0)
    {
        // not needed, remove it
        if (view)
        {
            [view removeFromSuperview];
            [self.headerViewsDictionary removeObjectForKey:[NSString stringWithFormat:@"%i", sectionNumber]];
            view = nil;
        }
    }
    else if(!view)
    {
        // needed, but not available, create it and add it as a subview

        view = [self headerViewForSection:sectionNumber];

        if (!self.headerViewsDictionary && view)
            self.headerViewsDictionary = [NSMutableDictionary dictionary];

        if (view)
        {
            [self.headerViewsDictionary setValue:view forKey:[NSString stringWithFormat:@"%i", sectionNumber]];

            [self.view addSubview:view];
        }
    }


    [view setFrame:viewFrame];
}
}
此外,我们还需要声明一个属性,以保持视图可见:

@property (nonatomic, strong) NSMutableDictionary* headerViewsDictionary;
这些方法返回标题视图的大小和X轴偏移:

-(CGSize)headerSize
{
return CGSizeMake(44.0f, 44.0f);
}

-(CGFloat)headerXOrigin
{
return 10.0f;
} 
我已经构建了代码,以便删除任何不需要的标题视图,因此我们需要一种方法,可以在需要时返回视图:

-(UIView*)headerViewForSection:(NSInteger)index
{
UIImageView* view = [[UIImageView alloc] init];

if (index % 2)
{
    [view setImage:[UIImage imageNamed:@"call"]];
}
else
{
    [view setImage:[UIImage imageNamed:@"mail"]];
}

return view;
}
下面是它的外观:

它在lanscape中的外观如何,我使用了控件在tableView的左侧显示44px


希望这有帮助:)。

要处理这种重叠的怪癖,我们可以尝试使用
UIScrollViewDelegate
-scrollViewDidScroll:
?我也会尽我所能,但至少你的小原型看起来很有希望。谢谢@马蒂亚斯:我设法得到了想要的结果。请参见下面我的答案weet和simple实现。恭喜!聪明的解决方案!