iOS 调整导航栏按钮与边框的距离

2020-09-10  本文已影响0人  大成小栈

废话少说,直接上干货!👇

1. 一个设置按钮相对于navBar约束的类

.h文件

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, MANavBarBtnPosition) {
    MANavBarBtn_Left,
    MANavBarBtn_Right
};

NS_ASSUME_NONNULL_BEGIN

@interface MANavBarBtnView : UIView

@property (nonatomic, assign) MANavBarBtnPosition position;

+ (void)setupNavBarBtnWithNavItem:(UINavigationItem *)navItem view:(UIView *)view position:(MANavBarBtnPosition)position;

@end

NS_ASSUME_NONNULL_END

.m 文件

#import "MANavBarBtnView.h"

#define Margin  10.0

@interface MANavBarBtnView () {
    BOOL applied;
}

@end

@implementation MANavBarBtnView

- (void)layoutSubviews {
    [super layoutSubviews];
    
    if (applied || [[[UIDevice currentDevice] systemVersion] doubleValue] < 11.0) {
        return;
    }
    
    UIView *view = self;
    while (![view isKindOfClass:[UINavigationBar class]] && [view superview] != nil) {
        view = [view superview];
        if ([view isKindOfClass:[UIStackView class]] && [view superview] != nil) {
            if (self.position == MANavBarBtn_Left) {
                [view.superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:view.superview attribute:NSLayoutAttributeLeading multiplier:1.0 constant:Margin]];
                applied = YES;
            }
            else if (self.position == MANavBarBtn_Right) {
                [view.superview addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:view.superview attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-Margin]];
                applied = YES;
            }
            break;
        }
    }
}


+ (void)setupNavBarBtnWithNavItem:(UINavigationItem *)navItem view:(UIView *)view position:(MANavBarBtnPosition)position {
    
    if ([UIDevice currentDevice].systemVersion.floatValue >= 11.0) {
        MANavBarBtnView *barBtnView = [[MANavBarBtnView alloc] initWithFrame:view.frame];
        [barBtnView setPosition:position];
        [barBtnView addSubview:view];
        
        UIBarButtonItem *btnItem = [[UIBarButtonItem alloc] initWithCustomView:barBtnView];
        if (position == MANavBarBtn_Left) {
            [navItem setLeftBarButtonItem:btnItem];
        } else {
            [navItem setRightBarButtonItem:btnItem];
        }
    } else {
        UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:NULL];
        [space setWidth:-Margin];
        
        NSArray *items = @[space, [[UIBarButtonItem alloc] initWithCustomView:view]];
        if (position == MANavBarBtn_Left) {
            [navItem setLeftBarButtonItems:items];
        } else {
            [navItem setRightBarButtonItems:items];
        }
    }
}

@end

2. 使用过程

在有导航栏的Controller中,按如下方式调用即可,如设置左侧返回按钮:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [self setupBackItem];
}

// 设置返回按钮
- (void)setupBackItem {
    
    if (self.navigationController.topViewController && self.navigationController.viewControllers.firstObject != self) {
        [MANavBarBtnView setupNavBarBtnWithNavItem:self.navigationItem view:[self backButton] position:MANavBarBtn_Left];
    }
}

- (UIButton *)backButton {
    
    UIImage *normalImage = [[UIImage kk_imageNamed:@"ma_icon_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [backButton setImage:normalImage forState:UIControlStateNormal];
    backButton.frame = CGRectMake(.0, .0, 35.0, 40.0);
    backButton.imageEdgeInsets = UIEdgeInsetsMake(.0, -8.0, .0, 8.0);
    backButton.tintColor = [self.page.window.navigationBarTextStyle isEqualToString:@"white"]? [UIColor whiteColor]: [UIColor blackColor];
    [backButton addTarget:self action:@selector(backButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    
    return backButton;
}

使用过程中,请注意 MANavBarBtnView 与初始化 navigationItem 时的 customView 之间的区别。

上一篇下一篇

猜你喜欢

热点阅读