iOS 的控件,只看到 UIButton 可以设置 Padding/Insets,即按钮上文字或图片与按钮边界的间隙,对与 CSS 来说叫做 Padding,在 iOS 中叫做 Insets,UIButton 设置 Insets 相应的属性如下:

Configuring Edge Insets

      contentEdgeInsets  property
      titleEdgeInsets  property
      imageEdgeInsets  property 

它们接受的属性类型是:UIEdgeInsets,由函数 UIEdgeInsetsMake ( CGFloat top, CGFloat left, CGFloat bottom, CGFloat right );     构造出,分别表示其中的内容/标题/图片离各边的距离。

在 xib 中也有界面来对按钮的这三个 EdgeInsets 属性的设置,分别是按钮的 Edge 和 Inset 属性。


办法当然还是有的,自定义相应自己的控件了,比如 InsetsLabel 或是  InsetsTextField,接着就是覆盖某些个方法来达成。

首先来看 UILabel 的子类 InsetsLabel 的实现代码:


//1.header file 
       #import <UIKit/UIKit.h> 

                  

       @interface InsetsLabel : UILabel 
       @property(nonatomic) UIEdgeInsets insets; 
       -(id) initWithFrame:(CGRect)frame andInsets: (UIEdgeInsets) insets; 
       -(id) initWithInsets: (UIEdgeInsets) insets; 
       @end 

                  

       //2. implementation file 
       #import "InsetsLabel.h" 

                  

       @implementation InsetsLabel 
       @synthesize insets=_insets; 
       -(id) initWithFrame:(CGRect)frame andInsets:(UIEdgeInsets)insets { 
           self = [super initWithFrame:frame]; 
           if(self){ 
               self.insets = insets; 
           } 
           return self; 
       } 

                  

       -(id) initWithInsets:(UIEdgeInsets)insets { 
           self = [super init]; 
           if(self){ 
               self.insets = insets; 
           } 
           return self; 
       } 

                  

       -(void) drawTextInRect:(CGRect)rect { 
           return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)]; 
       }
//1.header file 
       #import <UIKit/UIKit.h> 

                  

       @interface InsetsLabel : UILabel 
       @property(nonatomic) UIEdgeInsets insets; 
       -(id) initWithFrame:(CGRect)frame andInsets: (UIEdgeInsets) insets; 
       -(id) initWithInsets: (UIEdgeInsets) insets; 
       @end 

                  

       //2. implementation file 
       #import "InsetsLabel.h" 

                  

       @implementation InsetsLabel 
       @synthesize insets=_insets; 
       -(id) initWithFrame:(CGRect)frame andInsets:(UIEdgeInsets)insets { 
           self = [super initWithFrame:frame]; 
           if(self){ 
               self.insets = insets; 
           } 
           return self; 
       } 

                  

       -(id) initWithInsets:(UIEdgeInsets)insets { 
           self = [super init]; 
           if(self){ 
               self.insets = insets; 
           } 
           return self; 
       } 

                  

       -(void) drawTextInRect:(CGRect)rect { 
           return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)]; 
       }


关键就是覆盖了 -(void) drawTextInRect: (CGRect) rect; 方法,在画  Label 的文本时分别设置文本与  Label 四个边的间隙,即画在 Label 内的一个小矩形内,这个例子提供了便利的构造函数,提供自己的 UIEdgeInsets 属性。另外,函数 UIEdgeInsetsInsetRect(CGRect, UIEdgeInsets) 应该是好理解的。

再看如何设置 UITextField 中文本到四边的间距,这里也可以定义自己的 InsetsTextField:


// 
       //  Created by Unmi on 11/2/11. 
       //  Copyright (c) 2011 http://unmi.cc. All rights reserved. 
       // 

                  

       #import <UIKit/UIKit.h> 

                  

       @interface InsetsTextField : UITextField 
       @end 

                  

       @implementation InsetsTextField 
       //控制 placeHolder 的位置,左右缩 20 
       - (CGRect)textRectForBounds:(CGRect)bounds { 
           return CGRectInset( bounds , 20 , 0 ); 
       } 

                  

       // 控制文本的位置,左右缩 20 
       - (CGRect)editingRectForBounds:(CGRect)bounds { 
           return CGRectInset( bounds , 20 , 0 ); 
       } 
       @end 

                  

       //----------------------------------------------------------------- 
       //下面是使用 InsetsTextField 的代码,可放在 viewDidLoad 等代理方法中 
       InsetsTextField *insetTextField = [[InsetsTextField alloc] 
                                         initWithFrame:CGRectMake(10, 10, 180, 25)]; 

                  

       //须手动设置它的 borderStyle, 不然看不到边框的 
       insetsTextField.borderStyle = UITextBorderStyleRoundedRect; 
       [self.view addSubview:insetsTextField]; 
       [insetsTextField release];


效果如下:




上面更像是借鉴的 InsetsLabel 的实现,其实对于 UITextField 还有更好的实现办法,而且更简单,因为 UITextFiled 原来就支持的做法。比如它可以让你做出在文本框最前方固定一个 $ 符号,表示这个文本框是输入钱的,第一个$ 是不能被删除的。确实,你可以在 TextField 上贴个 Label,然后文本框的光标后移,稍显麻烦了。

而 UITextField 可以直接设置 leftView 或 rightView, 然后文本输入区域就在 leftView 和 rightView 之间了,看例子:


UILabel *paddingView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 10, 25)]; 
       paddingView.text = @"$"; 
       paddingView.textColor = [UIColor darkGrayColor]; 
       paddingView.backgroundColor = [UIColor clearColor]; 
       textfield.leftView = paddingView; 
       textfield.leftViewMode = UITextFieldViewModeAlways;


rightView 也是一样的设置方式,其中的  Mode 有四种,看到名字应该不难理解:

    UITextFieldViewModeNever,
    UITextFieldViewModeWhileEditing,
    UITextFieldViewModeU