2010-08-04 4 views
1

У музыкального приложения на iPad есть довольно много интересных пользовательских функций пользовательского интерфейса, одним из которых является представление таблицы, отображаемое при просмотре albums of a particular artist.UITableView с изображениями заголовков боковых секций

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

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

Любые мысли?


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

ответ

0

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

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

Пример кода:

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

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

1

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

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

+0

На самом деле, сочетание обоих звуков довольно эффективно. Добавление поднабора в представлении таблицы, которое находится рядом с ячейками, наряду с «отступом» ячеек, чтобы таблица и вид сбоку не перекрывались. –

+1

да. Я считаю, что это забавный эксперимент пользовательского интерфейса в любом случае, и id будет интересоваться, если вы сможете получить желаемые результаты :) –

+0

Ну, видимо, это возможно, так как я сделал это с моим прототипом. Но это требует большой помощи со стороны datasource/delegate, а также для «отступов» ячеек и заголовков разделов. Не могу понять, как сделать все это самодостаточным в самом представлении таблицы, но я думаю, я не могу быть слишком придирчивым. –

0

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

Я не подклассифицировал UITableView, я только что просмотрел разделы с помощью метода scrollViewDidScroll и добавил заголовки слева от tableView (так что вам нужно будет поместить viewview вправо в представлении 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 надеюсь, что это поможет :).