[iOS]iOS 7的Navigation适配解决方案


使用自定义UIView替换UINavigationBar,在ViewDidLoad中setNavigationBarHidden:YES;
自定义UIView的实现--CustomNavView
CustomNavView.h


 #import <UIKit/UIKit.h>

@interface CustomNavView : UIView
@property (weak, nonatomic) IBOutlet UILabel *titleLb;
@property (weak, nonatomic) IBOutlet UIImageView *bgImageView;
@property (nonatomic,strong) UIButton *leftBtn;
@property (nonatomic,strong) UIView *titleView;
@property (nonatomic,strong) NSArray *rightBtnArr;

-(void)hideNavWithAnimation:(BOOL)isAnimation;
-(void)showNavWithAnimation:(BOOL)isAnimation;
@end

这里对leftBtn只设置了一个,而rightBtn使用了数组,支持了多个Btn,可以根据自己项目的需求使leftBtn支持多个按钮。hide于show方法是为了支持项目中上滑隐藏于下滑显示的效果,同样可以用于navView的显示与隐藏。titleView与titleLb有点重复了。我在项目中使用了XIB,使用纯代码应该更好。

.m实现:


 - (id)initWithFrame:(CGRect)frame{
    self = [[[NSBundle mainBundle] loadNibNamed:@"CustomNavView" owner:self options:nil] objectAtIndex:0];
    if (self) {
        frame.size.height=IS_IOS_7?64:44;
        self.frame=frame;
        _rightBtnArr=[[NSArray alloc] init];
        _leftBtn=[UIButton buttonWithType:UIButtonTypeCustom];
        _titleView=[[UIView alloc] init];
    }
    return self;
}

-(void)layoutSubviews{
    [super layoutSubviews];
    if (IS_IOS_7) {
        self.frame=CGRectMake(0, 0, 320, 64);
    }else{
        self.frame=CGRectMake(0, 0, 320, 44);
        self.titleLb.center=self.center;
    }
}

在layout中把view的frame重新设置回来,防止再初始化的时候大小设置失误(其实初始化的时候直接使用init方法就够了,而且layout方法会被一直调用)。


 -(void)hideNavWithAnimation:(BOOL)isAnimation{
    [UIView animateWithDuration:0.4 animations:^{
        self.frame=CGRectMake(0,-44,320,(IS_IOS_7?:64:44));
        self.titleView.alpha=0;
        self.leftBtn.alpha=0;
        [self hideRightBtns];
    }];
}

-(void)showNavWithAnimation:(BOOL)isAnimation{
    [UIView animateWithDuration:0.4 animations:^{
        self.frame=CGRectMake(0,0,320,(IS_IOS_7?:64:44));
        self.titleView.alpha=1;
        self.leftBtn.alpha=1;
        [self showRightBtns];
    }];
}

用0.4秒的动画来hide与show。


 -(void)hideRightBtns{
    for (UIButton *btn in _rightBtnArr) {
        btn.alpha=0;
    }
}

-(void)showRightBtns{
    for (UIButton *btn in _rightBtnArr) {
        btn.alpha=1;
    }
}

这里没有判断数组中是否真的是UIButton,不安全(- - 为什么我没有改,因为项目实在急着适配,又是一扇破窗……)


 -(void)setRightBtnArr:(NSArray *)rightBtnArr{
    if (_rightBtnArr.count>0) {
        for (UIButton *btn in _rightBtnArr) {
            [btn removeFromSuperview];
        }
    }
    _rightBtnArr=rightBtnArr;
    CGFloat xTag=0.0;
    for (UIButton *btn in rightBtnArr) {
        CGRect btnFrame=btn.frame;
        btnFrame.origin.x=320-btn.frame.size.width-xTag;
        if (IS_IOS_7) {
            btnFrame.origin.y=(self.frame.size.height+20-_leftBtn.frame.size.height)/2;
        }else{
            btnFrame.origin.y=(self.frame.size.height-_leftBtn.frame.size.height)/2;
        }
        btn.frame=btnFrame;
        [self addSubview:btn];
        xTag=320-btnFrame.origin.x;
    }
}

设置rightBtnArr的时候需要把原来的那些Btn从View上移除掉,不然就是各种叠加,然后再把新的Btn加上去。


 -(void)setLeftBtn:(UIButton *)leftBtn{
    _leftBtn=leftBtn;
    CGRect btnFrame=_leftBtn.frame;
    btnFrame.origin.x=0;
    if (IS_IOS_7) {
        btnFrame.origin.y=(self.frame.size.height+20-_leftBtn.frame.size.height)/2;
    }else{
        btnFrame.origin.y=(self.frame.size.height-_leftBtn.frame.size.height)/2;
    }
    _leftBtn.frame=btnFrame;
    [self addSubview:_leftBtn];
}

-(void)setTitleView:(UIView *)titleView{
    _titleView=titleView;
    _titleView.center=CGPointMake(self.center.x, IS_IOS_7==YES?self.center.y+10:self.center.y);
    [self addSubview:_titleView];
}

写在最后:这只是一种应急的适配方案,能够做到快速的进行适配,但是对于可扩展性、重用性与可维护性来说还是比较差的,打算再做一个自定义的UINavigationController这样用起来应该更加方便!

ios 屏幕适配 ios7

无聊的杏仁 11 years, 9 months ago

好的设计就是尽量使用原生的东西,不然当项目大了的时候,自定义的东西,很容易就脱离你的控制了,因为你引用别人的东西,别人都调用的原生的东西。

绯弹亚里亚 answered 11 years, 9 months ago

Your Answer