转载

iOS笔记060 - 自定义控件

自定义tabBar

  • 系统自带的tabBar不能满足需求
  • 自己定义UITabBar

    • 自定义一个类继承自UITabBar
    • 实现initWithFrame和layoutSubviews方法即可。

iOS笔记060 - 自定义控件

//#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方法
  • 这样做得依据是

    • , 只会生成方法的声明, 不会生成方法的实现和带有_下划线的成员变量
    • 所以可以直接写几个关于这个常用属性的方法
#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效果

iOS笔记060 - 自定义控件

/**  * 设置顶部的标签栏  */ - (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;  }]; } 

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

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

iOS笔记060 - 自定义控件

//#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 
正文到此结束
Loading...