自定義UILabel UITextField 填充


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 屬性。

印像中,Swing 的許多組件均可設置 Insets 屬性,可對於 iOS 的控件就沒那麼幸運了,好比我想設置 UILable 或 UITextField 中的文本離邊界的間隙,無倫是在 xib 裏仍是直接代碼的方式都無能爲力,由於它們根據未開放相應的屬性讓你去控制。

辦法固然仍是有的,自定義相應本身的控件了,好比 InsetsLabel 或是  InsetsTextField,接着就是覆蓋某些個方法來達成。

首先來看 UILabel 的子類 InsetsLabel 的實現代碼:less

#import <UIKit/UIKit.h>

@interface SOInsetsLabel : UILabel


@property(nonatomic)UIEdgeInsets insets;

-(id)initWithFrame:(CGRect)frame andInsets: (UIEdgeInsets)insets;

-(id)initWithInsets: (UIEdgeInsets)insets;

@end
#import "SOInsetsLabel.h"

@implementation SOInsetsLabel

@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)];
}

@end


關鍵就是覆蓋了 -(void) drawTextInRect: (CGRect) rect; 方法,在畫  Label 的文本時分別設置文本與  Label 四個邊的間隙,即畫在 Label 內的一個小矩形內,這個例子提供了便利的構造函數,提供本身的 UIEdgeInsets 屬性。另外,函數 UIEdgeInsetsInsetRect(CGRect, UIEdgeInsets) 應該是好理解的。

再看如何設置 UITextField 中文本到四邊的間距,這裏也能夠定義本身的 InsetsTextField:函數

#import <UIKit/UIKit.h>

@interface SOInsetsTextField : UITextField

@end
#import "SOInsetsTextField.h"

@implementation SOInsetsTextField


//控制placeHolder 的位置,左右縮 20

- (CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectInset( bounds , 20 , 0 );
}

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

@end

 



//下面是使用
 InsetsTextField 的代碼,可放在 viewDidLoad 等代理方法中

ui

InsetsTextField *insetTextField = [[InsetsTextField alloc] initWithFrame:CGRectMake(10,10, 180, 25)];

//須手動設置它的 borderStyle, 否則看不到邊框的
insetsTextField.borderStyle = UITextBorderStyleRoundedRect;

[self.view addSubview:insetsTextField];

 



效果以下:atom



Unmi InsetsTextField

上面更像是借鑑的 InsetsLabel 的實現,其實對於 UITextField 還有更好的實現辦法,並且更簡單,由於 UITextFiled 原來就支持的作法。好比它可讓你作出在文本框最前方固定一個 $ 符號,表示這個文本框是輸入錢的,第一個$ 是不能被刪除的。確實,你能夠在 TextField 上貼個 Label,而後文本框的光標後移,稍顯麻煩了。

而 UITextField 能夠直接設置 leftView 或 rightView, 而後文本輸入區域就在 leftView 和 rightView 之間了,看例子:spa

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,
    UITextFieldViewModeUnlessEditing,
    UITextFieldViewModeAlways

它的效果呢就更酷了:

Unmi TextField LeftView RightView文本框的起始光標是從上圖數字 1 位置開始的。

實際應用中,對於 UITextField 若是有相似的需求,我會堅決果斷的使用 leftView/rightView 屬性來設置。

參考:1. http://stackoverflow.com/questions/2694411/text-inset-for-uitextfield
            2. http://stackoverflow.com/questions/5674655/uitextfield-align-left-margin

代理

相關文章
相關標籤/搜索