UIEdgeInsets 说明

本文介绍如何为UILabel和UITextField设置内边距(Padding),通过创建自定义子类实现,并展示了利用UITextField的leftView和rightView属性来调整文本框内文本的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设置 UILabel 和 UITextField 的 Padding 或 Insets

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 的实现代码:

//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];

效果如下:

Unmi InsetsTextField

上面更像是借鉴的 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,
    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

本文链接 http://unmi.cc/uilable-uitextfield-padding-insets, 来自 隔叶黄莺 Unmi Blog


<think>好的,我现在需要回答用户关于`image?.resizableImage`的问题。首先,我要确定用户提到的这个代码是来自哪个编程语言或框架。看起来像是Swift或者Objective-C的语法,因为iOS开发中常用`UIImage`的`resizableImage`方法。 接下来,我需要回忆`resizableImage`的具体用法和功能。这个方法通常用于创建可调整大小的图片,通过指定拉伸区域,让图片在不同尺寸下保持正确显示。比如按钮背景图,可以拉伸中间部分而保持边角不变。 然后,用户代码中有一个问号`image?`,这可能是在Swift中使用可选链式调用,确保当`image`为`nil`时不会崩溃。需要解释这种安全机制的作用。 还要考虑用户可能的背景,可能是iOS开发者,在处理图片拉伸时遇到了问题,或者想了解如何正确使用这个方法。需要提供具体的参数说明,比如`capInsets`和`resizingMode`,以及示例代码。 需要检查是否有常见的误区,比如是否理解`capInsets`是UIEdgeInsets,如何设置四个边的保留区域。另外,`resizingMode`的不同选项,如`.tile`和`.stretch`的区别。 最后,确保回答结构清晰,分点说明,并给出实际例子,帮助用户理解如何应用这个方法到实际开发中。避免使用过于专业的术语,保持解释的易懂性。</think>关于 `image?.resizableImage` 的使用,这是一个 iOS 开发中处理图片拉伸的典型方法(适用于 Swift/Objective-C)。具体解释如下: --- ### 核心概念 `resizableImage` 是 `UIImage` 的实例方法,用于创建**可自适应尺寸的图片**。通过定义图片的拉伸区域,使图片在不同尺寸的视图中保持特定区域不变形。 --- ### 典型使用场景 1. 聊天气泡背景 2. 按钮的按压状态背景 3. 任何需要自适应视图尺寸的图案背景 --- ### 参数详解(Swift 语法) ```swift let resizableImage = originalImage?.resizableImage( withCapInsets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), resizingMode: .stretch // 或 .tile ) ``` 1. **capInsets(边缘保护区域)** - `UIEdgeInsets(top: T, left: L, bottom: B, right: R)` - 定义图片四个方向不拉伸的区域 - 示例:`top:10` 表示顶部保留10pt不拉伸 2. **resizingMode(拉伸模式)** - `.stretch`:线性拉伸中间区域 - `.tile`:平铺重复中间区域(适合有纹理的图片) --- ### 可视化示例 原图尺寸 20x20pt: ``` ┌────┬────┐ │ A │ B │ ├────┼────┤ │ C │ D │ └────┴────┘ ``` 设置 `capInsets = UIEdgeInsets(top:5, left:5, bottom:5, right:5)` 后: - A/B/C/D 四个角落保持原样 - 中间横竖线条会被拉伸/平铺 --- ### 注意事项 1. **可选值处理**:`image?` 中的问号是 Swift 的可选链调用,当图片为 nil 时不会崩溃 2. **@3x图片适配**:建议使用矢量格式图片或提供 3 倍图保证清晰度 3. **性能优化**:对于频繁使用的拉伸图,建议缓存结果 实际开发中常见的错误是未正确计算 capInsets 值,可以通过 Xcode 的 `Debug View Hierarchy` 工具实时查看拉伸效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值