Twitter-Like滚动标题

时间:2014-12-01 21:34:49

标签: ios objective-c xcode twitter uiscrollview

在Twitter iOS应用中,当您在导航栏下方的个人资料部分中滚动浏览您的姓名时,您的名称将开始滚动到导航栏本身的视图中,如果您向下滚动,则会在那里粘贴。

我想知道如何实施类似的效果以及最好的方法。 它看起来好像:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

可能是一个不错的选择,但不完全确定如何让它滚动到视图中而不是简单地在达到特定的顶部偏移时动画它。

我使用自定义标题视图而非UINavigationBar,因此不需要特定于此,但最适合使用UILabel。

更喜欢Objective-C但欢迎Swift。

可爱的示例图片: Twitter Header

3 个答案:

答案 0 :(得分:7)

我在这里工作了。这个ViewController以简单的UINavigationController

呈现
@interface ViewController () <UIScrollViewDelegate>
{
    UIScrollView *titleView;
    UIScrollView *contentView;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self.view setBackgroundColor:[UIColor lightGrayColor]];

    [self setTitle:@"My Title"];

    titleView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 44.0)];
    [titleView setContentSize:CGSizeMake(0.0, 88.0)];
    [self.view addSubview:contentView];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 44.0, CGRectGetWidth(titleView.frame), 44.0)];
    [titleLabel setTextAlignment:NSTextAlignmentCenter];
    [titleLabel setFont:[UIFont boldSystemFontOfSize:17.0]];
    [titleLabel setText:self.title];
    [titleView addSubview:titleLabel];


    self.navigationItem.titleView = titleView;


    contentView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    [contentView setContentSize:CGSizeMake(0.0, 4000.0)];
    [contentView setDelegate:self];
    [self.view addSubview:contentView];

    UILabel *contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.bounds), 44.0)];
    [contentLabel setTextAlignment:NSTextAlignmentCenter];
    [contentLabel setFont:[UIFont boldSystemFontOfSize:17.0]];
    [contentLabel setText:self.title];
    [contentView addSubview:contentLabel];
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGPoint contentOffset = CGPointMake(0.0, MIN(scrollView.contentOffset.y + 64.0, 44.0));
    [titleView setContentOffset:contentOffset];
}

@end

答案 1 :(得分:6)

上面的代码很好,清晰,只用于滚动标题。

但是如果你想创建一个与Twitter相同的视图,你可以使用本教程:

http://www.thinkandbuild.it/implementing-the-twitter-ios-app-ui/

本教程在swift中实现。

您可以点击本教程末尾的“下载源”按钮下载源代码。

或直接转到github: https://github.com/ariok/TB_TwitterUI

下面我们将解释如何实现功能scrollViewDidScroll:

1-这些是scrollViewDidScroll函数的第一行:

var offset = scrollView.contentOffset.y
var avatarTransform = CATransform3DIdentity
var headerTransform = CATransform3DIdentity

这里我们得到当前的垂直偏移,我们初始化两个转换,我们将在稍后使用此函数进行设置。

2-管理下拉动作

if offset < 0 {

     let headerScaleFactor:CGFloat = -(offset) / header.bounds.height
     let headerSizevariation = ((header.bounds.height * (1.0 + headerScaleFactor)) - header.bounds.height)/2.0
     headerTransform = CATransform3DTranslate(headerTransform, 0, headerSizevariation, 0)
     headerTransform = CATransform3DScale(headerTransform, 1.0 + headerScaleFactor, 1.0 + headerScaleFactor, 0)

     header.layer.transform = headerTransform
}

3-管理向上/向下滚动

else{
  // Header -----------

   headerTransform = CATransform3DTranslate(headerTransform, 0, max(-offset_HeaderStop, -offset), 0)

//  ------------ Label

   let labelTransform = CATransform3DMakeTranslation(0, max(-distance_W_LabelHeader, offset_B_LabelHeader - offset), 0)
            headerLabel.layer.transform = labelTransform

//  ------------ Blur

   headerBlurImageView?.alpha = min (1.0, (offset - offset_B_LabelHeader)/distance_W_LabelHeader)

// Avatar -----------

   let avatarScaleFactor = (min(offset_HeaderStop, offset)) / avatarImage.bounds.height / 1.4 // Slow down the animation
   let avatarSizeVariation = ((avatarImage.bounds.height * (1.0 + avatarScaleFactor)) - avatarImage.bounds.height) / 2.0
   avatarTransform = CATransform3DTranslate(avatarTransform, 0, avatarSizeVariation, 0)
   avatarTransform = CATransform3DScale(avatarTransform, 1.0 - avatarScaleFactor, 1.0 - avatarScaleFactor, 0)

   if offset <= offset_HeaderStop {

      if avatarImage.layer.zPosition < header.layer.zPosition{
                    header.layer.zPosition = 0
                }

      }else {
        if avatarImage.layer.zPosition >= header.layer.zPosition{
                    header.layer.zPosition = 2
                }
            }}

4-应用转换

header.layer.transform = headerTransform
avatarImage.layer.transform = avatarTransform

答案 2 :(得分:3)

感谢Code Ryan,它在我的项目中运行良好。代码有一些错误,但我修复了它,这是Swift中的版本,万一有人需要它。

    self.title = "My Title"
    titleView = UIScrollView(frame: CGRectMake(0.0, 0.0, 100.0, 44.0))
    titleView.contentSize = CGSizeMake(0.0, 88.0)
    self.view.addSubview(titleView)

    var titleLabel:UILabel = UILabel(frame: CGRectMake(0.0, 44.0, CGRectGetWidth(titleView.frame), 44.0))
    titleLabel.textAlignment = NSTextAlignment.Center
    titleLabel.font = UIFont(name: "HelveticaNeue-UltraLight", size: 17)
    titleLabel.text = self.title
    titleView.addSubview(titleLabel)

    self.navigationItem.titleView = titleView

    contentView = UIScrollView(frame: self.view.bounds)
    contentView.contentSize = CGSizeMake(0.0, 4000.0)
    contentView.delegate = self
    self.view.addSubview(contentView)

    var contentLabel:UILabel = UILabel(frame: CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.bounds), 44.0))
    contentLabel.textAlignment = NSTextAlignment.Center
    contentLabel.font = UIFont(name: "HelveticaNeue-UltraLight", size: 17)
    contentLabel.text = self.title
    contentView.addSubview(contentLabel)

override func scrollViewDidScroll(scrollView: UIScrollView){

    var contentnOffset:CGPoint = CGPointMake(0.0, min(scrollView.contentOffset.y + 64.0, 44.0))
    titleView.setContentOffset(contentnOffset, animated: true)

}