UIButton-内部布局

1.自定义UIButton更改内部的布局的原因

  •   通常我们用系统的UIButton,设置完ImageView跟textLabel的属性之后,图片在左边,文字在右边,有时候我们需要图片在右边,文字在左边就需要自定义了

2.更改内部子控件布局的方式有两种

调整Button内部子控件的步骤

        1.自定义Button

        2.调整位置

            1>重写两个方法:titleRectForContentRect:和imageRectForContentRect:

            2>重写layoutSubviews: 先调用super方法.之后自己调整frame

        3.如果需要设置imageView和titleLabel的属性时,在initWithFrame:方法设置
 // 1.创建UIButton对象
    MSHButton *btn = [MSHButton buttonWithType:UIButtonTypeCustom];
    这里是外界的使用,创建
    // 2.设置frame
    btn.frame = CGRectMake(100, 100, 175, 50);
    
    // 3.设置背景颜色
    [btn setBackgroundColor:[UIColor purpleColor]];
    
    // 4.设置btn显示的文字
    [btn setTitle:@"普通按钮" forState:UIControlStateNormal];
    
    // 5.设置btn显示的图片
    [btn setImage:[UIImage imageNamed:@"miniplayer_btn_playlist_normal"] forState:UIControlStateNormal];
    
    // 添加到控制器的View中
    [self.view addSubview:btn];
    
    // 6.设置btn中titleLabel/imageView的背景颜色
    btn.titleLabel.backgroundColor = [UIColor blueColor];
    btn.imageView.backgroundColor = [UIColor orangeColor];
    
    // 7.调整titleLabel/imageView的位置
    // 注意:不管外界如何调整btn的titleLabel/imageView的位置,button内部都会调整回去
    /*
    btn.titleLabel.frame = CGRectMake(0, 0, 120, 50);
    btn.imageView.frame = CGRectMake(120, 0, 55, 50);
     */
    /*
    btn.titleLabel.textAlignment = NSTextAlignmentCenter;
    btn.imageView.contentMode = UIViewContentModeCenter;
     */

我们看一下其内部的实现原理
#import "MSHButton.h"

@implementation MSHButton

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
        self.imageView.contentMode = UIViewContentModeCenter;
    }
    return self;
}

#pragma mark - 方案一:调整titleLabel和imageView的frame
/*
// 调整titleLabel的frame
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(0, 0, 120, 50);
}

// 调整imageView的frame
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
    return CGRectMake(120, 0, 55, 50);
}
 */

#pragma makr - 方案二:重写layoutSubviews
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // 设置子控件的frame
    self.titleLabel.frame = CGRectMake(0, 0, 120, 50);
    self.imageView.frame = CGRectMake(120, 0, 55, 50);
}

但是前两种都需要设置子控件的frame,下面有一种比较好的方法

@implementation MSHTitleButton
// 调整子控件的位置
//- (CGRect)titleRectForContentRect:(CGRect)contentRect
//- (CGRect)imageRectForContentRect:(CGRect)contentRect

- (void)setTitle:(NSString *)title forState:(UIControlState)state{
    [super setTitle:title forState:state];
    
    // 自动计算尺寸
    [self sizeToFit];
}
- (void)setImage:(UIImage *)image forState:(UIControlState)state{

    [super setImage:image forState:state];
    // 自动计算尺寸
    [self sizeToFit];
}
- (void)layoutSubviews{

    [super layoutSubviews];
    判断title的x值是不是大于ImageView的X说明,说明是第一次来到该方法中布局,在以后每一次自定义的button尺寸修改之后都会来到该方法,那么以后就直接退出
    if (self.imageView.x < self.titleLabel.x) {
//            NSLog(@"%s",__func__);
        // 第一次
        //调整子控件的位置
        // 1.Label 的位置
        self.titleLabel.x = self.imageView.x;
        // 2.调整imageView 的位置
        self.imageView.x = CGRectGetMaxX(self.titleLabel.frame);
    }
    
    
}

 

 
posted @ 2016-01-03 01:45  mshong  阅读(529)  评论(0编辑  收藏  举报