Можно ли добавить фиксированный контент в UIScrollView?
Я хочу создать подкласс UITableView
или UIScrollView
который будет иметь некоторое затенение сверху, когда смещение содержимого> 0 означает, что контент прокручивается. (См. Изображение прилагается) ![enter image description here]()
То, как я реализую это сейчас, - это использовать UIViewController
который является делегатом tableView
. У меня просто есть GradientView
поверх tableView
, и я перехватываю scrollViewDidScroll:
для анимации видимости этого верхнего градиента.
Моя проблема с этой реализацией заключается в том, что она не "чиста". Я хочу, чтобы мои UIViewControllers
позаботились о логике, а не UIViewControllers
применения градиентов и т.д. Хотел бы я просто удалить подкласс UITableView
, который сделает это для меня.
Проблема для меня заключается в том, что я не могу понять, как tableView
может добавить к себе фиксированный контент поверх прокручиваемого содержимого.
Другой вопрос: какой метод /UIScrollView
я должен переопределить для перехвата события прокрутки. Очевидно, я не хочу, чтобы tableView был делегатом сам по себе...
Есть идеи?
Благодарю!
Ответы
Ответ 1
Хорошо, поэтому я нашел решение на Apple WWDC 2011 Session 104 video - Advanced Scroll View Techniques.
В этом видеоролике есть целый раздел о "Стационарных представлениях" в представлении прокрутки. Согласно Apple, здесь можно переопределить layoutSubviews и поместить туда весь код, чтобы разместить все, что захотите, где бы вы ни захотели.
Я попробовал это, и это на самом деле довольно легко и работает как ожидалось.
Например, если бы я хотел, чтобы теневой заголовок находился над таблицей при прокрутке содержимого, это код, который я должен написать:
-(void) layoutSubviews
{
[super layoutSubviews];
[self positionTopShadow];
}
-(void) positionTopShadow
{
CGFloat yOffset = self.contentOffset.y;
// I'm doing some limiting so that the maximum height of the shadow view will be 40 pixels
yOffset = MIN(yOffset, 40);
yOffset = MAX(0, yOffset);
CGRect frame = self.topShadowView.frame;
// The origin should be exactly like the content offset so it would look like
// the shadow is at the top of the table (when it actually just part of the content)
frame.origin = CGPointMake(0, self.contentOffset.y);
frame.size.height = yOffset;
frame.size.width = self.frame.size.width;
self.topShadowView.frame = frame;
if (self.topShadowView.superview == nil)
{
[self addSubview:self.topShadowView];
}
[self bringSubviewToFront:self.topShadowView];
}
Ответ 2
Мне удалось найти гораздо более простой способ сделать это, чем это сделал Авраам.
Я использую тот факт, что UIScrollView вызывает scrollViewDidScroll: когда-либо пиксель изменений прокрутки для установки объекта в месте смещения. Ниже мой полный код, чтобы сохранить серый стол в верхней части scrollview при перемещении:
- (void)viewDidLoad {
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(5.0, 50.0, self.bounds.size.width - 15.0, self.bounds.size.height - 60.0)];
[scrollView setBackgroundColor:[UIColor colorWithRed:251.0/255.0 green:251.0/255.0 blue:251.0/255.0 alpha:1.0]];
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width + 500, 1000.0)];
[scrollView setDelegate:self];
[self addSubview:scrollView];
UIView* header = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, scrollView.contentSize.width, 40.0)];
[header setTag:100];
[header setBackgroundColor:[UIColor darkGrayColor]];
[scrollView addSubview:header];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIView* header = [self viewWithTag:100];
[header setFrame:CGRectMake(0.0, scrollView.contentOffset.y, header.bounds.size.width, header.bounds.size.height)];
}
Ответ 3
Вы можете попробовать использовать метод viewForHeaderInSection таблицыView для затененного вида (а также heightForHeaderInSection)... Сделайте заштрихованную часть как заголовок. Таким образом, существует фиксированный контент поверх прокручиваемого содержимого.
Ответ 4
#define kImageOriginHight 300
- (void)scrollViewDidScroll:(UIScrollView *)scrollView1{
CGFloat yOffset = scrollView1.contentOffset.y;
// NSLog(@" y offset := %f", yOffset);
//zoom images and hide upper view while scrooling to down position
if (yOffset < 0) {//-kImageOriginHight
CGRect f = imgV.frame;
f.origin.y = yOffset;
f.size.height = -yOffset + kImageOriginHight;
imgV.frame = f;
//viewTableUpperView.alpha = 1.5 - (yOffset/-kImageOriginHight);
//viewTableUpperView.userInteractionEnabled = NO;
if(yOffset+0.5 == -kImageOriginHight){
[UIView animateWithDuration:0.1 animations:^{
//viewTableUpperView.alpha = 1.0;
}];
//viewTableUpperView.userInteractionEnabled = YES;
}
}
}