ios7:实现类似于人人、safari的可动态调整大小的导航条以及类似于雅虎天气的全透明导航条

****转载请注明出处

一、可动态调整大小的导航条

要想调整导航条(NavigationBar)的大小或位置,只需改变他的frame即可。
但怎样让导航条上的那些控件(按钮、标题、searchbar之类的)也能成一定比例的缩小或者消失呢?当然是对这些视图做仿射变换(CGAfineTransfrom)。
我们知道UIBarButtonItem继承自UIBarItem,UIBarItem继承自NSObject,不能对它做一些UIView能做的仿射变换。
但是NavigationController.navigationItem有一个属性:titleView可作为我们自定义控件(所有继承自UIView的控件)的容器。

实现动态导航条的思路:当检测要触发调整导航条的事件时(scrollView向下向上滚动或Tap导航条等等),1、将导航条向上移动20个Point(因为状态栏的宽度是20),当然移动多少个Point你随意。2、对titleView上的控件做仿射变换

我们先来给导航条布局: 以下代码可放在ViewDidLoad里
    UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 44)];
    contentView.tag = 1;
    self.navigationItem.titleView = contentView;
    
    UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
    leftButton.center = CGPointMake(13, 22);//设置frame不行调整,但center确行
    leftButton.tag = 4;
    [leftButton setTitle:@"left" forState:UIControlStateNormal];
    [leftButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [leftButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
    [contentView addSubview:leftButton];
    
    UIButton *rightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
    rightButton.tag = 2;
    [rightButton setTitle:@"right" forState:UIControlStateNormal];
    [rightButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [rightButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
    rightButton.center = CGPointMake(280, 22);
    [contentView addSubview:rightButton];
    
    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.tag = 3;
    titleLabel.text = @"title";
    [titleLabel sizeToFit];
    titleLabel.center = CGPointMake(contentView.frame.size.width / 2, 22);
    [contentView addSubview:titleLabel];

创建控件的代码都很简单,比较蛋疼的就是计算它们的位置。还有不要忘了给他们上个tag以便下面能得到这些视图的引用。
如果给titleView上个背景色,我们可以发现titleView的Frame,感觉有点奇怪,不知道苹果为什么这样做。但这并不意味着你的Subview只能在这个Frame以内,把Subview.frame.origin.x设置为负数就可以在它之外了嘛,效果如下图(我把导航条的背景色设置成了粉红)



下面实现调整导航条大小
static BOOL isShirink = 0;
- (void)shrinkNavBar{
    UIView *contentView = [self.navigationItem.titleView viewWithTag:1];

    UILabel *titleLabel = (UILabel *)[contentView viewWithTag:3];
    UIButton *leftButton = (UIButton *)[contentView viewWithTag:4];
    UIButton *rightButton = (UIButton *)[contentView viewWithTag:2];
    
    CGPoint labelCenter = titleLabel.center;
    CGPoint leftButtonCenter = leftButton.center;
    CGPoint rightButtonCenter = rightButton.center;
    
    CGRect navBarFrame = self.navigationController.navigationBar.frame;
    
    CGAffineTransform labelTransform = CGAffineTransformMakeScale(0.9, 0.9);
    CGAffineTransform buttonTransform = CGAffineTransformMakeScale(0.01, 0.01);
    if (!isShirink) {
        
        navBarFrame.origin.y -= 20;
        
        labelCenter.y += 5;
        leftButtonCenter.x -= 5;
        rightButtonCenter.x += 5;
        
        [UIView animateWithDuration:0.5 animations:^{
            titleLabel.transform = labelTransform;
            leftButton.transform = buttonTransform;
            rightButton.transform = buttonTransform;
            self.navigationController.navigationBar.frame = navBarFrame;
            titleLabel.center = labelCenter;
            leftButton.center = leftButtonCenter;
            rightButton.center = rightButtonCenter;
        }];
        isShirink = ! isShirink;
    }else{
        navBarFrame.origin.y += 20;
        labelCenter.y -= 5;
        leftButtonCenter.x += 5;
        rightButtonCenter.x -= 5;
        
        
        [UIView animateWithDuration:0.5 animations:^{
            titleLabel.transform = CGAffineTransformIdentity;
            leftButton.transform = CGAffineTransformIdentity;
            rightButton.transform = CGAffineTransformIdentity;
            self.navigationController.navigationBar.frame = navBarFrame;
            titleLabel.center = labelCenter;
            leftButton.center = leftButtonCenter;
            rightButton.center = rightButtonCenter;
        }];
        isShirink = !isShirink;
    }
}


说明:用一个static的bool变量检查导航条的状态。 如果导航条没有被压缩, 就用UIView的 +animateWithDuration:animations:^(void)animation{}做压缩的动画效果。这里有个问题:导航条向上移动了,那么它的所有子视图也向上移动,这样使得titleLabel太靠近状态栏,我们想把它的位置往下调一些怎么做?

CGAfineTransformMakeScale是以view.layer.anchorPoint(锚点)为基准进行变换,这个点默认是(0.5,0.5)。view还有一个属性center,如果在scale变换的同时改变center的值,就可以调整它的位置,labelCenter.y += 5 向下调整5个单位。 注意以下,CGAfineTransform和center相互关联,并且都会改变frame的值,这之间的关系可以自己思考以下。

如果导航条已经被压缩,将以上操作倒过来就OK了。 CGAffineTransformIdentity可以把view恢复成没做仿射变换,这也是view.transform的默认值。

为了简单起见。我就以Tap导航条手势触发调整大小
讲以下代码添加进第一段代码的末尾:
    UITapGestureRecognizer *tapGestureReconizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(shrinkNavBar)];
    tapGestureReconizer.numberOfTapsRequired = 1;
    tapGestureReconizer.numberOfTouchesRequired = 1;
    [contentView addGestureRecognizer:tapGestureReconizer];

Perfect!

二、全透明导航条

只需要3行代码:
    [self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    [self.navigationBar setShadowImage:[UIImage new]];
    [self.navigationBar setTranslucent:YES];

效果如图:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值