iOS笔记060 - 自定义控件

自定义tabBar

  • 系统自带的tabBar不能满足需求
  • 自己定义UITabBar
    • 自定义一个类继承自UITabBar
    • 实现initWithFrame和layoutSubviews方法即可。

//#import "SLQTabBar.h"
@interface SLQTabBar ()
/**发布按钮*/
@property (nonatomic, strong) UIButton *publishBtn;
@end
@implementation SLQTabBar
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        // 添加一个自定义按钮到tabBar
        UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [addBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
        [addBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];

        [self addSubview:addBtn];
        self.publishBtn = addBtn;
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    // 设置发布按钮的frame
    self.publishBtn.frame =CGRectMake(0, 0, self.publishBtn.currentBackgroundImage.size.width, self.publishBtn.currentBackgroundImage.size.height);
    self.publishBtn.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);

    // 设置其他item的位置
    CGFloat x = 0.0;
    CGFloat y = 0;
    CGFloat width = self.frame.size.width / 5;
    CGFloat height = self.frame.size.height;

    NSInteger index = 0;
    for (UIView *btn in self.subviews) {
        // 判断按钮属性
        if(![btn isKindOfClass:NSClassFromString(@"UITabBarButton")] || (btn == self.publishBtn))
//        if (![btn isKindOfClass:[UIControl class]] || (btn == self.publishBtn))
        {
            continue;
        }
        // 计算x坐标
        x = ((index > 1)?(index + 1):index ) * width; // 跳过加号按钮,然后继续设置frame
        btn.frame = CGRectMake(x, y, width, height);

        // 索引增加
        index ++;
    }
}

自定义UIView工具类

  • 因为要经常获取控件的frame、height等属性进行设置,这里对UIView写一个分类,添加一些自定义的setter和getter方法
  • 这样做得依据是
    • 分类中声明@property, 只会生成方法的声明, 不会生成方法的实现和带有_下划线的成员变量
    • 所以可以直接写几个关于这个常用属性的方法
#import <UIKit/UIKit.h>

@interface UIView (SLQExtension)
/** 在分类中声明@property, 只会生成方法的声明, 不会生成方法的实现和带有_下划线的成员变量*/

/**height*/
@property (nonatomic, assign) CGFloat height;
/**width*/
@property (nonatomic, assign) CGFloat width;
/**size*/
@property (nonatomic, assign) CGSize size;
/**x*/
@property (nonatomic, assign) CGFloat x;
/**y*/
@property (nonatomic, assign) CGFloat y;

@end

//#import "UIView+SLQExtension.h"

@implementation UIView (SLQExtension)

- (void)setWidth:(CGFloat)width
{
    CGRect rect = self.frame;
    rect.size.width = width;
    self.frame = rect;
}

- (CGFloat)width
{
    return self.frame.size.width;
}

- (void)setHeight:(CGFloat)height
{
    CGRect rect = self.frame;
    rect.size.height = height;
    self.frame = rect;
}

- (CGFloat)height
{
    return self.frame.size.height;
}

- (void)setSize:(CGSize)size
{
    CGRect rect = self.frame;
    rect.size = size;
    self.frame = rect;
}

- (CGSize)size
{
    return self.frame.size;
}

- (void)setY:(CGFloat)y
{
    CGRect rect = self.frame;
    rect.origin.y = y;
    self.frame = rect;
}

- (CGFloat)y
{
    return self.frame.origin.y;
}

- (void)setX:(CGFloat)x
{
    CGRect rect = self.frame;
    rect.origin.x = x;
    self.frame = rect;
}

- (CGFloat)x
{
    return self.frame.origin.x;
}

@end

自定义scrollView

  • 按钮添加指示器以及实现滚动view效果

/**
 *  设置顶部的标签栏
 */
- (void)setTitlesView
{
    // 一个UIView + 5个UIButton
    UIView *titleView = [[UIView alloc] init];
    titleView.backgroundColor = SLQRGBColor(241, 241, 241);
    // 指定尺寸和位置
    titleView.frame = CGRectMake(0, 64, self.view.width, 44);
    NSArray *title = @[@"全部",@"视频",@"声音",@"图片",@"段子"];
    // 添加5个按钮
    CGFloat x = 0;
    CGFloat width = titleView.width / title.count;
    for (NSInteger i = 0 ; i < 5;  i ++) {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        x = i * width;
        btn.frame = CGRectMake(x, 0, width, titleView.height);
        [btn setTitle:title[i] forState:UIControlStateNormal];
        [btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
        [titleView addSubview:btn];
    }

    // 添加底部指示条indicator
    UIView *indicatorView = [[UIView alloc] init];
    indicatorView.backgroundColor = [UIColor redColor];
    // 位置动态计算,添加到按钮底部
    indicatorView.height = 2;
    indicatorView.y = titleView.height - indicatorView.height;

    [titleView addSubview:indicatorView];

    self.indicatorView = indicatorView;
    [self.view addSubview:titleView];
}
/**
 *  点击按钮首先切换指示器的位置
 */
- (void)titleClick:(UIButton *)btn
{
    [UIView animateWithDuration:0.1 animations:^{
        // 设置位置
        self.indicatorView.width = btn.titleLabel.width;
        self.indicatorView.centerX = btn.centerX;
    }];
}

自定义的子控制器的返回按钮

  • 如果想要保持整个应用中额返回按钮一致,可以这样实现

//#import "SLQNavigationController.h"

@implementation SLQNavigationController

// 自定义导航控制器,在弹出窗口之前设置返回按钮样式。
// 每一个控制器弹出之前都会调用这个方法,所以可以保证所有的控制器的返回按钮样式一致。
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // 判断是不是第一个控制器,如果不是就设置返回按钮
    if (self.childViewControllers.count > 0) {
        UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        // 设置图片
        [backBtn setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
        [backBtn setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
        [backBtn setTitle:@"返回" forState:UIControlStateNormal];
        // 让按钮内部的所有内容左对齐
        backBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

        backBtn.size = CGSizeMake(70, 30);
        // 文字颜色
        [backBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [backBtn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
        // 设置内边距,使得按钮紧靠边
        [backBtn setContentEdgeInsets:UIEdgeInsetsMake(0, -15, 0, 0)];

        [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];

        viewController.navigationItem.leftBarButtonItems = @[
                                                             [[UIBarButtonItem alloc] initWithCustomView:backBtn]
                                                             ];
        // 隐藏tabBar
        viewController.hidesBottomBarWhenPushed = YES;

    }
    // 设置过控制器后再弹出
    // 这句super的push要放在后面, 让viewController可以覆盖上面设置的leftBarButtonItem
    [super pushViewController:viewController animated:animated];
}
- (void)back
{
    [self popViewControllerAnimated:YES];
}
@end

自定义按钮

  • 按钮默认显示是图片在左,文字在右
  • 如果想实现其他排列,如文字在下,图片在上,可以重写layoutSubviews方法
//#import "SLQVerticalButton.h"

@implementation SLQVerticalButton

- (void)setup
{
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
}
/**
 *  通过xib创建按钮
 */
- (void)awakeFromNib
{
    [self setup];
}
/**
 *  通过代码创建按钮
 */
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}
/**
 *  重新布局子控件
 */
- (void)layoutSubviews
{
    [super layoutSubviews];
    // 调整imageView位置
    self.imageView.x = 0;
    self.imageView.y = 0;
    self.imageView.width = self.width;
    self.imageView.height = self.imageView.width;

    // 调整lable位置
    self.titleLabel.x = 0;
    self.titleLabel.y = self.imageView.height;
    self.titleLabel.width = self.width;
    self.titleLabel.height = self.height - self.imageView.height;
}
@end

你可能感兴趣的:(iOS笔记060 - 自定义控件)