1

iPad 上的音乐应用程序有很多有趣的自定义 UI 功能,其中之一是查看特定艺术家的专辑时显示的表格视图。

它在每个部分的侧面都有图像,几乎以与部分标题视图非常相似的方式起作用。如果我向下滚动,顶部图像会一直留在那里,直到下一张图像出现将其关闭,反之亦然。

最初,如果不重新实现 UITableView 似乎是不可能的,但我认为它是半可行的,只需将 UITableView 子类化以在 uitableview 之外的侧面绘制这些部分图像,无论何时调用layoutSubviews(即每当它滚动时)。这有一些小问题:因为它在 UITableView 之外绘制,所以任何自动调整大小都可能会导致整个布局关闭。我真的只是不确定这一切的可行性。

有什么想法吗?


编辑:我刚刚意识到我的第一个想法是行不通的,因为图像侧本身的任何触摸都不会被 tableview 跟踪,所以如果你触摸那里就无法滚动。我认为这里最大的问题是弄清楚如何传播触摸,以便在整个视图中跟踪触摸。

4

3 回答 3

1

您可以以某种方式检查您在 tableview 中(或最顶层等)中的哪个部分,然后只需有一个 UIView 在该部分更改时更新,我的想法有点难以解释,但它与完全重做 UITableView,只需在表格视图旁边有另一个视图来执行图像,而不是尝试嵌入该功能。

另一种方法可能更棘手,但您可以尝试缩进您的单元格,以便它们不会从表格视图的最左侧开始,使表格视图非常宽,并在包含该的部分标题中有一个自定义视图图像在其左侧,希望能正确执行吗?好问题和一个有趣的问题。

于 2010-08-04T22:28:50.957 回答
0

半夜胡乱想了想,终于想出了一个真正的解决办法。

将 UITableview 嵌入到 UIScrollView 中,当用户滚动视图时,触摸会通过父滚动视图,而不是 tableview 本身。您需要做的几乎所有事情都在 layoutSubviews 方法中;因为每当用户滚动视图时都会调用滚动视图的 layoutSubviews,只需更改表格视图的框架以保持固定在屏幕上,并更改表格视图的 contentOffset 以匹配滚动视图的内容。

示例代码:

- (void) layoutSubviews{
    tableView.frame = CGRectMake(self.contentOffset.x, self.contentOffset.y, tableView.frame.size.width, tableView.frame.size.height);
    tableView.contentOffset = self.contentOffset;   
}

此时,您可以将 tableview 调整到一侧,并在另一侧做任何您想做的事情。

于 2010-08-09T16:21:34.420 回答
0

好的,我做了类似于音乐应用程序和聚光灯搜索所做的事情。

我没有继承 UITableView,我只是通过它的 scrollViewDidScroll 方法跟踪了各个部分,并将标题视图添加到 tableView 的左侧(因此您必须将 tableview 放在 viewController 视图的右侧,这意味着您可以t 使用 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

在横向 希望这可以帮助 :)。

于 2012-09-26T14:25:31.033 回答