Заголовки UITableView на левой стороне разделов (например, Spotlight) - PullRequest
6 голосов
/ 03 марта 2011

Давно искал это, и я до сих пор не нашел способа сделать это.Я хотел бы воспроизвести заголовки разделов Spotlight на iPhone в UITableView.

«Обычные» заголовки табличного представления остаются видимыми в верхней части раздела при прокрутке, как мы все знаем.Но есть один вид заголовка, который я никогда не видел нигде, кроме как на странице Spotlight в Springboard: там заголовки охватывают всю высоту раздела и не застряли в верхней части раздела, а на левой стороне.

Как, черт возьми, это достигается?

Ответы [ 3 ]

5 голосов
/ 03 марта 2011

Хороший вопрос. Я провел небольшой эксперимент. Это почти похоже на вид из центра внимания. Но ему не хватает одной функции импорта. Нижнее «изображение» не толкает верхнее изображение к вершине, если они сталкиваются.

Я сомневаюсь, что есть встроенное решение без использования частных фреймворков.


Я достиг этого: enter image description here

Как вы можете видеть, два изображения заголовка сверху перекрываются. Они не толкают друг друга как обычные заголовки. И мне пришлось деактивировать разделители клеток. Если бы я использовал их, они появились бы во всей камере. Таким образом, вы должны нарисовать их самостоятельно. Не так уж и важно.

Но я понятия не имею, как я мог бы исправить перекрытие.

Вот код, который сделал это:

- (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];
}
4 голосов
/ 26 сентября 2012

Хорошо, я сделал нечто похожее на то, что делает поиск музыкальных приложений и прожекторов.

У меня нет подкласса UITableView, я просто отслеживал разделы с помощью его метода scrollViewDidScroll и добавил представления заголовков слева от tableView (так что вам нужно будет поместить table view вправо в представление 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;
}

вот как это будет выглядеть:

the section's header is moving out of the screen as it's section does

the section's header is moving with the section's origin

Как это будет выглядеть в lanscape, я использовал ограничения, чтобы дать 44px слева от tableView

in landscape orientation надеюсь, это поможет:).

0 голосов
/ 14 июля 2012
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...