Горизонтальный UIScrollView внутри UITableViewCell
Я пытаюсь создать тот же эффект, что и в приложении AppStore для просмотра скриншотов: внутри UITableView у меня есть пользовательские подклассы UITableViewCell. Один из них предназначен для показа предварительного просмотра какого-либо продукта, скажем, 4 изображений. Я хочу, чтобы они отображались так же, как AppStore представляет скриншоты приложения: внутри горизонтального UIScrollView с его подключенным UIPageControl.
Итак, я добавляю свой UIScrollView и мой UIPageControl в свой UITableViewCell, вот так:
@implementation phVolumePreviewCell
- (id)init {
if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kVolumePreviewCellIdentifier]) {
[self setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
[self setSelectionStyle:UITableViewCellSeparatorStyleNone];
previews = [[NSMutableArray alloc] initWithCapacity:4];
for (int i = 0; i < 4; i++) {
[previews addObject:@"dummy"];
}
scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
[scrollView setPagingEnabled:YES];
[scrollView setBackgroundColor:[UIColor grayColor]];
[scrollView setIndicatorStyle:UIScrollViewIndicatorStyleBlack];
[scrollView setShowsHorizontalScrollIndicator:YES];
[scrollView setBounces:YES];
[scrollView setScrollEnabled:YES];
[scrollView setDelegate:self];
[self.contentView addSubview:scrollView];
[scrollView release];
pageControl = [[UIPageControl alloc] initWithFrame:CGRectZero];
[pageControl setNumberOfPages:[previews count]];
[pageControl setBackgroundColor:[UIColor grayColor]];
[self.contentView addSubview:pageControl];
[pageControl release];
}
return self;
}
(примечание: я заполняю "предварительные просмотры" фиктивными данными здесь, просто чтобы иметь [просмотр], который работает, я хочу просмотреть индикатор прокрутки scrollView только для тестовых целей, я их скрою позже далее).
Моя проблема в том, что я могу прокрутить весь UITableView, содержащий этот phVolumePreviewCell (подкласс UITableViewCell), но я не могу прокрутить UIScrollView. Как я могу достичь этого?
Единственная найденная мной информация: http://theexciter.com/articles/touches-and-uiscrollview-inside-a-uitableview.html
Но он говорит о старых SDK (а именно, 2.2), и я уверен, что для этого существует более "недавний" подход.
Некоторые замечания:
- Я могу прокрутить UIScrollView двумя пальцами. Это не то, что я хочу, я хочу, чтобы он мог прокручивать только одним пальцем.
- Когда я прокручиваю двумя пальцами, TableView по-прежнему перехватывает касания и немного прокручивается вверх или вниз. Я бы хотел, чтобы TableView придерживался своего положения, когда я касаюсь ScrollView.
Я считаю, что мне нужно разобраться, как перехватывать штрихи на моем TableView, и если прикосновение относится к подклассу phVolumePreviewCell (пользовательский подкласс UITableViewCell), передайте его в ячейку, а не обрабатывайте его в TableView.
Для записи мой TableView создается программно в подклассе UITableViewController:
@interface phVolumeController : UITableViewController <UITableViewDelegate> {
LocalLibrary *lib;
NSString *volumeID;
LLVolume *volume;
}
- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID;
@end
@implementation phVolumeController
#pragma mark -
#pragma mark Initialization
- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID {
if (self = [super initWithStyle:UITableViewStylePlain]) {
lib = [newLib retain];
volumeID = newVolumeID;
volume = [(LLVolume *)[LLVolume alloc] initFromLibrary:lib forID:volumeID];
[[self navigationItem] setTitle:[volume title]];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier];
if (cell == nil) {
cell = [[[phVolumePreviewCell alloc] init] autorelease];
}
[(phVolumePreviewCell *)cell setVolume:volume];
return (UITableViewCell *)cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return kVolumePreviewCellHeight;
}
Спасибо за любую помощь!
Ответы
Ответ 1
Я нашел обходное решение.
Восстанавливая с нуля очень простой UITableView (8 строк) и вставляя UIScrollView только во вторую строку, отлично работает. Вложенные представления прокрутки (TableView и ScrollView) прокручиваются независимо, как и ожидалось. Все, что было сделано в однофайловом тестовом проекте, в AppDelegate.
Итак... сначала я подумал: "Это может быть проблема с делегацией", поэтому я сказал scrollView, что его делегатом был TableView, а не мой собственный подкласс TableViewCell. Безрезультатно.
Затем вместо использования специального, чистого подкласса TableViewCell, который просто добавляет ScrollView и PageControl, я прибегал к созданию простого TableViewCell в методе cellViewRightAtIndexPath: TableView. Затем я создаю UIScrollView сразу после инициализации TableViewCell, а затем добавляю его в TableViewCell и shazam... он работает!
До:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier];
if (cell == nil) {
cell = [[[phVolumePreviewCell alloc] init] autorelease];
}
[(phVolumePreviewCell *)cell setVolume:volume];
// That does the job of creating the cell scrollView and pageControl
return (UITableViewCell *)cell
После:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kvcPreviewRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kvcPreviewRowIdentifier] autorelease];
previewScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, kvcPreviewScrollViewHeight)];
[previewScrollView setContentSize:CGSizeMake(1000, kvcPreviewScrollViewHeight)];
[[cell contentView] addSubview:previewScrollView];
previewPageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, kvcPreviewScrollViewHeight, tableView.frame.size.width, kvcPreviewPageControlHeight)];
[previewPageControl setNumberOfPages:4];
[[cell contentView] addSubview:previewPageControl];
}
return (UITableViewCell *)cell;
Как получается, когда я создаю свой scrollView из подкласса TVCell, он не играет хорошо; но когда я создаю scrollView из TableView сразу после создания "классического" TVCell, он работает?
Я мог бы найти решение, но я все еще озадачен причиной.