• iOS UIButton 设置图片文字垂直排列


    在实际的iOS项目开发中,我们经常需要改变系统的控件的样式,自己定义一个,同样的当我们发现系统自带的某些方法不好使时,我们也会想到重写这个方法。 本文主要记录笔者设置UIButton图片文字垂直排列的方法,最终解决了在图片和文字垂直排列的情况下,如果文字长度变化会导致图片位置变动的问题,对 于此问题网上有比较多的做法,我就不多说了,在此记录这点细节仅为加深印象并方便以后查阅。如有纰漏还请见谅

    方案一:通过调整按钮图片和文字的内边距

    UIEdgeInsets

    typedef struct UIEdgeInsets {
        CGFloat top, left, bottom, right;  // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
    } UIEdgeInsets;
    

    在UIButton中有三个对EdgeInsets的设置:ContentEdgeInsets、titleEdgeInsets、imageEdgeInsets

    @property(nonatomic)          UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR; // default is UIEdgeInsetsZero
    @property(nonatomic)          UIEdgeInsets titleEdgeInsets;                // default is UIEdgeInsetsZero
    @property(nonatomic)          BOOL         reversesTitleShadowWhenHighlighted; // default is NO. if YES, shadow reverses to shift between engrave and emboss appearance
    @property(nonatomic)          UIEdgeInsets imageEdgeInsets;                // default is UIEdgeInsetsZero

    UIEdgeInsetsMake

    里面的四个参数表示距离上边界、左边界、下边界、右边界的距离,默认都为零,title/image在button的正中央

    UIKIT_STATIC_INLINE UIEdgeInsets UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) {
        UIEdgeInsets insets = {top, left, bottom, right};
        return insets;
    }
    @interface UIButton (UIButtonExt)  
    - (void)centerImageAndTitle:(float)space;  
    - (void)centerImageAndTitle;  
    @end  
     
    @implementation UIButton (UIButtonExt)  
    - (void)centerImageAndTitle:(float)spacing  
    {      
        // get the size of the elements here for readability  
        CGSize imageSize = self.imageView.frame.size;  
        CGSize titleSize = self.titleLabel.frame.size;  
     
        // get the height they will take up as a unit  
        CGFloat totalHeight = (imageSize.height + titleSize.height + spacing);  
     
        // raise the image and push it right to center it  
        self.imageEdgeInsets = UIEdgeInsetsMake(- (totalHeight - imageSize.height), 0.0, 0.0, - titleSize.width);  
     
        // lower the text and push it left to center it  
        self.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (totalHeight - titleSize.height),0.0);      
    }  
     
    - (void)centerImageAndTitle  
    {  
        const int DEFAULT_SPACING = 6.0f;  
        [self centerImageAndTitle:DEFAULT_SPACING];  
     }  
    @end
    后面经过测试,如果button的文字长度变更,会导致图片位置变化,经过多次修改UIEdgeInsets的值也没有达到期望效果,最终我们采用下述方案:自定义按钮继承系统的UIButton,重写layoutSubviews方法,布局子控件,调整按钮内imageView的Center和titleLabel的Frame解决上述问题。 
    方案二

    -(void)layoutSubviews {
        [super layoutSubviews];
     
        // Center image
        CGPoint center = self.imageView.center;
        center.x = self.frame.size.width/2;
        center.y = self.imageView.frame.size.height/2;
        self.imageView.center = center;
     
        //Center text
        CGRect newFrame = [self titleLabel].frame;
        newFrame.origin.x = 0;
        newFrame.origin.y = self.imageView.frame.size.height + 5;
        newFrame.size.width = self.frame.size.width;
     
        self.titleLabel.frame = newFrame;
        self.titleLabel.textAlignment = UITextAlignmentCenter;
    }

    这里笔者采取方案二示例如下:

    #import "BSQuickLoginButton.h"
    
    @implementation BSQuickLoginButton
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        //调整图片(imageView)的位置和尺寸
        CGPoint center = self.imageView.center;
        center.x = self.frame.size.width/2;
        center.y = self.imageView.frame.size.height/2;
        self.imageView.center = center;
        
        
        //调整文字(titleLable)的位置和尺寸
       CGRect newFrame = self.titleLabel.frame;
        newFrame.origin.x = 0;
        newFrame.origin.y = self.imageView.frame.size.height;
        
        newFrame.size.width = self.frame.size.width;
        newFrame.size.height = self.frame.size.height - self.imageView.frame.size.height;
        
        self.titleLabel.frame = newFrame;
        
        
       //让文字居中
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
    }
    @end

       这里值得注意的一个小细节是:允许直接修改对象的结构体属性,但不能直接修改对象的结构体属性的成员,所以这里我们不能直接拿到按钮的frame属性的赋值设置,需要先设置一个临时的tempFrame,然后在赋值给按钮的frame.

    如图所示:会提示表达式不可被指定不可分配的错误

    另外,开发中我们经常会写self.imageView.frame.size.height一类繁琐的重复的代码,这里我们可以采取一种偷懒的小技巧:
    给控件(UIView)写一个分类 如下:
    #import "UIView+Extension.h"
    
    @implementation UIView (Extension)
    
    - (void)setX:(CGFloat)x
    {
        CGRect frame = self.frame;
        frame.origin.x = x;
        self.frame = frame;
    }
    
    - (CGFloat)x
    {
        return self.frame.origin.x;
    }
    
    - (void)setY:(CGFloat)y
    {
        CGRect frame = self.frame;
        frame.origin.y = y;
        self.frame = frame;
    }
    
    - (CGFloat)y
    {
        return self.frame.origin.y;
    }
    
    - (void)setWidth:(CGFloat)width
    {
        CGRect frame = self.frame;
        frame.size.width = width;
        self.frame = frame;
    }
    
    - (CGFloat)width
    {
        return self.frame.size.width;
    }
    
    - (void)setHeight:(CGFloat)height
    {
        CGRect frame = self.frame;
        frame.size.height = height;
        self.frame = frame;
    }
    
    - (CGFloat)height
    {
        return self.frame.size.height;
    }
    
    - (void)setCenterX:(CGFloat)centerX
    {
        CGPoint center = self.center;
        center.x = centerX;
        self.center = center;
    }
    
    - (CGFloat)centerX
    {
        return self.center.x;
    }
    
    - (void)setCenterY:(CGFloat)centerY
    {
        CGPoint center = self.center;
        center.y = centerY;
        self.center = center;
    }
    
    - (CGFloat)centerY
    {
        return self.center.y;
    }
    
    @end

    与此同时,重写了frame的各属性的set、get方法,将不再受上述不能直接赋值的细节问题影响,上述方案代码亦可简化如下:

    - (void)awakeFromNib
    {
        self.titleLabel.textAlignment = NSTextAlignmentCenter;
    }
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        // 调整图片的位置和尺寸
        self.imageView.y = 0;
        self.imageView.centerX = self.width * 0.5;
        
        // 调整文字的位置和尺寸
        self.titleLabel.x = 0;
        self.titleLabel.y = self.imageView.height;
        self.titleLabel.width = self.width;
        self.titleLabel.height = self.height - self.titleLabel.y;
    }

    在项目实战中,笔者通过自定义按钮,实现了如下登录界面中快速登录按钮图片和文字垂直排列的样式需求,效果如下

    对 比:

     
     
     
     
  • 相关阅读:
    一生要做的99件事
    Flash 简单的Mouse.hide()
    [转]FCKeditor
    [转]pv是什么意思?什么是pv值,pv访问量?网站pv是什么?
    CSS:用DIV+CSS实现表格形式的数据排列
    css "Float"
    Jemin的div+css测试文件
    原来
    我终于知道什么情况下得用table了
    转的 关于div 的重叠
  • 原文地址:https://www.cnblogs.com/mysticCoder/p/4799778.html
Copyright © 2020-2023  润新知