UITableView с изображениями заголовка бокового сечения - PullRequest
1 голос
/ 05 августа 2010

Музыкальное приложение на iPad имеет довольно много интересных пользовательских функций пользовательского интерфейса, одна из которых - табличное представление, отображаемое при просмотре альбомов определенного исполнителя .

У этого есть изображения вдоль стороны каждого раздела, почти действуя очень похоже на представления заголовка раздела. Если я прокручиваю вниз, верхнее изображение остается там до тех пор, пока не появится следующее изображение, чтобы убрать его, и наоборот.

Изначально это кажется совершенно невозможным без переопределения UITableView заново, но я думаю, что это почти выполнимо, просто подклассифицируя UITableView, чтобы рисовать эти изображения секций на стороне, вне uitableview, всякий раз, когда он вызывает layoutSubviews (т.е. всякий раз, когда это прокручивается). Есть небольшие проблемы с этим: поскольку он рисует вне UITableView, любое автоматическое изменение размера, вероятно, отбросит весь макет. И я просто не уверен в целесообразности всего этого.

Есть мысли? <ч /> Изменить: я только что понял, что моя первая идея не будет работать в том, что любые касания на стороне изображения не будут отслеживаться в таблице, поэтому вы не можете прокрутить, если вы коснулись там. Я думаю, что самая большая проблема здесь заключается в том, чтобы выяснить, как распространять касания, чтобы касания отслеживались по всему виду.

Ответы [ 3 ]

1 голос
/ 05 августа 2010

вы можете как-то проверить, в каком разделе вы находитесь в виде таблицы (или на самом верху и т. Д.), А затем просто иметь UIView, который обновляется всякий раз, когда изменяется раздел, моя идея немного сложна для объяснения, но этого не будетчтобы вообще отменить UITableView, просто создайте изображения рядом с табличным представлением, вместо того, чтобы пытаться внедрить эту функциональность.

Другой способ сделать это, возможно, немного сложнее, но вы можете попробоватьчтобы сделать отступ для ваших ячеек, чтобы они не начинались в самой левой части табличного представления, чтобы сделать табличное представление очень широким и иметь настраиваемое представление в заголовке раздела, которое содержит это изображение слева и, надеюсь, будет ли это правильно?хороший вопрос, с которым интересно играть.

0 голосов
/ 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 голосов
/ 09 августа 2010

Подумав об этом случайно посреди ночи, я наконец-то нашел реальное решение.

Встраиваем UITableview в UIScrollView, и когда пользователь прокручивает представление, касания проходят черезродительский вид прокрутки, а не сам вид таблицы.Практически все, что вам нужно сделать, лежит в методе layoutSubviews;так как layoutSubviews scrollview вызывается всякий раз, когда пользователь прокручивает представление, просто измените рамку табличного представления, чтобы он оставался фиксированным на экране, и измените contentOffset табличного представления, чтобы он соответствовал тому из scrollview.

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

На этом этапе вы можете настроить вид таблицы в одну сторону и делать все, что вы хотите, с другой.

...