【问题标题】:Is it possible to add fixed content to a UIScrollView?是否可以将固定内容添加到 UIScrollView?
【发布时间】:2012-03-11 14:35:25
【问题描述】:

我想创建一个UITableView 或UIScrollView 的子类,当内容偏移量> 0 时,它的顶部会有一些阴影,表示内容是可滚动的。 (见附图)

我现在实现它的方式是使用UIViewController,它是tableView 的代表。我只是在tableView 上添加了一个GradientView,然后截取scrollViewDidScroll: 以动画化顶部渐变的可见性。

我对这个实现的问题是它不是“干净的”。我希望我的UIViewControllers 负责逻辑,而不是处理应用渐变和其他东西。我希望我可以删除 UITableView 的一个子类,它会为我做到这一点。

我面临的挑战是,我无法弄清楚tableView 如何在可滚动内容之上添加一个固定内容。

另一个问题是我应该重写UIScrollView 的什么方法来拦截滚动事件。显然我不希望 tableView 成为自己的代表......

有什么想法吗?

谢谢!

【问题讨论】:

    标签: iphone ios cocoa-touch ipad uiscrollview


    【解决方案1】:

    您可以尝试使用 tableView 的 viewForHeaderInSection 方法作为阴影视图(以及 heightForHeaderInSection)...将阴影部分作为标题。这样在可滚动内容的顶部有一个固定的内容。

    【讨论】:

    • 不够好,因为: A. 也许有一天我想要一个真正的标题。 B.即使内容偏移量为0,它仍然会在顶部。我希望只有在内容滚动时才会出现阴影。
    【解决方案2】:

    好的,所以我在 Apple 的 WWDC 2011 Session 104 视频 - 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's 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];
    }
    

    【讨论】:

    • 我相信你知道,你被允许(并且在这种情况下被鼓励)接受你自己的答案:)
    • @rokjarc 我相信你知道,你不能在 24 小时内接受你自己的答案...... :)
    • 是的,我想变得聪明:)
    • @rokjarc 我相信你知道,你很聪明——不要怀疑:)
    • 我在您的解决方案中遇到了问题。尝试与 UIRefreshControl 一起使用,刷新时,滚动视图的 contentOffset 似乎是错误的。
    【解决方案3】:

    我设法找到了一种比 Avraham 所做的更简单的方法。

    我使用 UIScrollView 调用 scrollViewDidScroll 的事实:每个像素滚动更改以将对象设置在偏移位置。以下是我在滚动视图顶部保持灰色条的完整代码:

    - (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)];
    }
    

    【讨论】:

    • 这个对我有用,我只是做了一些编辑..你需要添加 UIScrollViewDelegate..
    • 你是对的,我认为这暗示[scrollView setDelegate:self]; 意味着您还需要添加代理,感谢您为经验不足的用户澄清这一点。
    • 这只有在你想从 UIViewController 进行更改时才有效。如果你想要一个具有固定视图的自包含 UIScrollView 子类 - layoutSubviews 是要走的路。
    【解决方案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;
        }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-17
      • 2020-09-25
      • 1970-01-01
      • 2016-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多