使用catagory类别给控件加边框

本文介绍两种在Swift中简化UIButton边框颜色设置的方法,通过Category实现更便捷的代码复用,避免重复编写相同的边框设置代码。

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

在项目中经常需要给view button 等 加边框 每次都要自己堆代码 感觉很费劲

self.addWayBtn.layer.borderWidth=1;
self.addWayBtn.layer.borderColor=[UIColor colorWithRed:255/255.0 green:111/255.0 blue:1/255.0 alpha:1].CGColor;

这两句代码 写了一遍又一遍 实在是烦!既然圆角都可以用layer.cornerRadius在xib中keypath中写出那么为什么不把layer.borderColor也写进去呢

因为keypath 里边只有color所以我们就要用到catagory了

这里提供两种方式 都可以做到

方法1:

.h

@property (nonatomic,strong)UIColor*borderUIColor;

.m

-(void)setBorderUIColor:(UIColor *)color
{
    self.borderColor=color.CGColor;
}
-(UIColor*)borderUIColor
{
    return [UIColor colorWithCGColor:self.borderColor];
}

此时就可以使用属性啦:

162058_wJ07_2429434.png

 

方法2:

.h

@property(nonatomic, strong) UIColor *borderColorFromUIColor;
- (void)setBorderColorFromUIColor:(UIColor *)color;

.m
(记得引入头文件#import <objc/runtime.h>)


- (UIColor *)borderColorFromUIColor {
    
    return objc_getAssociatedObject(self, @selector(borderColorFromUIColor));
    
}

-(void)setBorderColorFromUIColor:(UIColor *)color

{
    
    objc_setAssociatedObject(self, @selector(borderColorFromUIColor), color, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self setBorderColorFromUI:[self borderColorFromUIColor]];
    
}

- (void)setBorderColorFromUI:(UIColor *)color

{
    
    self.borderColor = color.CGColor;
    
     NSLog(@"%@", color);
    
}

 

此时也可以使用了

162312_FClc_2429434.png

你get到了么?

转载于:https://my.oschina.net/rainwz/blog/680553

<think>我们参考了用户提供的引用,特别是引用[2]和引用[3]中关于自定义TextBox边框样式的实现方法。用户希望自定义TextBox的边框样式,包括改变边框颜色、实现鼠标悬停效果等。 实现思路: 1. 创建一个自定义控件,继承自TextBox。 2. 重写控件的创建参数(CreateParams)以设置初始边框样式(如果需要改变默认边框)。 3. 重写OnPaint事件,自定义绘制边框(这是主要方法)。 4. 处理鼠标事件(MouseEnter, MouseLeave)以实现悬停效果。 注意:由于TextBox是系统控件,其绘制主要由系统处理,因此我们通常不直接重绘整个控件,而是通过绘制边框来实现自定义样式。同时,我们需要考虑边框样式(BorderStyle)的设置。 步骤: 1. 创建自定义控件类,继承TextBox。 2. 添自定义属性,如边框颜色、悬停边框颜色等。 3. 重写OnPaint方法,在控件上绘制自定义边框。 4. 重写OnMouseEnter和OnMouseLeave方法,以改变边框颜色并触发重绘。 5. 考虑当BorderStyle为None时,我们绘制自定义边框;当BorderStyle为Fixed3D时,系统绘制3D边框,我们可能不需要自定义;当BorderStyle为FixedSingle时,我们可以覆盖系统绘制的边框。 根据引用[3]中的方法,我们可以设置BorderStyle为FixedSingle,然后通过自定义绘制覆盖掉系统绘制的边框。 具体实现:</think># C# 自定义 TextBox 边框样式实现方法 在 C# 中自定义 TextBox 边框样式可以通过创建自定义控件来实现,下面我将详细介绍完整的实现方案: ## 完整实现代码 ```csharp using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; [DefaultEvent("TextChanged")] public class CustomTextBox : TextBox { // 自定义属性 private Color _borderColor = Color.Gray; private Color _borderFocusColor = Color.Blue; private int _borderSize = 1; private bool _underlinedStyle = false; private bool _isFocused = false; private int _borderRadius = 0; // 构造函数 public CustomTextBox() { this.AutoSize = false; this.BackColor = SystemColors.Window; this.BorderStyle = BorderStyle.None; // 禁用默认边框 this.Padding = new Padding(5, 3, 5, 3); } // 自定义属性:边框颜色 [Category("自定义外观")] [Description("文本框边框颜色")] public Color BorderColor { get => _borderColor; set { _borderColor = value; this.Invalidate(); } } // 自定义属性:焦点边框颜色 [Category("自定义外观")] [Description("文本框获得焦点时的边框颜色")] public Color BorderFocusColor { get => _borderFocusColor; set { _borderFocusColor = value; if (_isFocused) this.Invalidate(); } } // 自定义属性:边框大小 [Category("自定义外观")] [Description("边框大小(像素)")] public int BorderSize { get => _borderSize; set { if (value >= 1) { _borderSize = value; this.Invalidate(); } } } // 自定义属性:下划线样式 [Category("自定义外观")] [Description("是否使用下划线样式")] public bool UnderlinedStyle { get => _underlinedStyle; set { _underlinedStyle = value; this.Invalidate(); } } // 自定义属性:圆角半径 [Category("自定义外观")] [Description("边框圆角半径")] public int BorderRadius { get => _borderRadius; set { if (value >= 0) { _borderRadius = value; this.Invalidate(); } } } // 重写OnPaint方法绘制自定义边框 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics graphics = e.Graphics; // 设置抗锯齿 graphics.SmoothingMode = SmoothingMode.AntiAlias; // 计算边框矩形 Rectangle borderRect = new Rectangle(0, 0, this.Width - 1, this.Height - 1); // 选择边框颜色 Color borderColor = _isFocused ? _borderFocusColor : _borderColor; // 绘制圆角边框 if (_borderRadius > 0) { using (GraphicsPath path = GetRoundedPath(borderRect, _borderRadius)) using (Pen penBorder = new Pen(borderColor, _borderSize)) { graphics.DrawPath(penBorder, path); } } // 绘制下划线样式 else if (_underlinedStyle) { using (Pen penBorder = new Pen(borderColor, _borderSize)) { graphics.DrawLine(penBorder, 0, this.Height - 1, this.Width, this.Height - 1); } } // 绘制普通矩形边框 else { using (Pen penBorder = new Pen(borderColor, _borderSize)) { graphics.DrawRectangle(penBorder, borderRect); } } } // 创建圆角路径 private GraphicsPath GetRoundedPath(Rectangle rect, int radius) { GraphicsPath path = new GraphicsPath(); float curveSize = radius * 2F; path.StartFigure(); path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90); path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90); path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90); path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90); path.CloseFigure(); return path; } // 处理焦点事件 protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); _isFocused = true; this.Invalidate(); } protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); _isFocused = false; this.Invalidate(); } // 处理尺寸变化 protected override void OnResize(EventArgs e) { base.OnResize(e); if (this.DesignMode) this.Invalidate(); } // 处理布局变化 protected override void OnLocationChanged(EventArgs e) { base.OnLocationChanged(e); if (this.DesignMode) this.Invalidate(); } } ``` ## 使用说明 ### 1. 添自定义控件到项目 - 在项目中添新类,命名为`CustomTextBox.cs` - 将上述代码复制到文件中 - 编译项目后,工具箱中将出现`CustomTextBox`控件 ### 2. 在窗体中使用自定义文本框 ```csharp public partial class MainForm : Form { public MainForm() { InitializeComponent(); // 创建自定义文本框 CustomTextBox txtUsername = new CustomTextBox { Location = new Point(50, 50), Size = new Size(200, 30), BorderColor = Color.Silver, BorderFocusColor = Color.DodgerBlue, BorderSize = 2, PlaceholderText = "用户名" }; // 创建下划线样式的文本框 CustomTextBox txtPassword = new CustomTextBox { Location = new Point(50, 100), Size = new Size(200, 30), BorderColor = Color.Gray, BorderFocusColor = Color.Blue, BorderSize = 2, UnderlinedStyle = true, PlaceholderText = "密码" }; // 创建圆角文本框 CustomTextBox txtEmail = new CustomTextBox { Location = new Point(50, 150), Size = new Size(200, 30), BorderColor = Color.LightGray, BorderFocusColor = Color.CornflowerBlue, BorderSize = 1, BorderRadius = 15, PlaceholderText = "邮箱" }; // 添到窗体 this.Controls.Add(txtUsername); this.Controls.Add(txtPassword); this.Controls.Add(txtEmail); } } ``` ### 3. 在属性窗口中自定义样式 在Visual Studio设计器中,选择CustomTextBox控件后,可以在属性窗口的"自定义外观"分类下设置: - **BorderColor**:默认边框颜色 - **BorderFocusColor**:获得焦点时的边框颜色 - **BorderSize**:边框宽度(像素) - **UnderlinedStyle**:是否使用下划线样式 - **BorderRadius**:圆角半径(0为直角) ## 高级功能扩展 ### 添占位符文本功能 ```csharp // 在CustomTextBox类中添以下代码 private string _placeholderText = ""; private Color _placeholderColor = Color.Gray; private bool _isPlaceholder = false; [Category("自定义外观")] [Description("占位符文本")] public string PlaceholderText { get => _placeholderText; set { _placeholderText = value; if (string.IsNullOrWhiteSpace(this.Text)) this.Invalidate(); } } [Category("自定义外观")] [Description("占位符文本颜色")] public Color PlaceholderColor { get => _placeholderColor; set { _placeholderColor = value; if (_isPlaceholder) this.Invalidate(); } } protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); if (!_isPlaceholder && string.IsNullOrWhiteSpace(this.Text)) SetPlaceholder(); else if (_isPlaceholder && !string.IsNullOrWhiteSpace(this.Text)) RemovePlaceholder(); } protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); if (_isPlaceholder) RemovePlaceholder(); } protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); if (string.IsNullOrWhiteSpace(this.Text)) SetPlaceholder(); } private void SetPlaceholder() { if (!string.IsNullOrWhiteSpace(_placeholderText)) { _isPlaceholder = true; base.Text = _placeholderText; this.ForeColor = _placeholderColor; this.Font = new Font(this.Font, FontStyle.Italic); } } private void RemovePlaceholder() { if (_isPlaceholder) { _isPlaceholder = false; base.Text = ""; this.ForeColor = this.ForeColor; this.Font = new Font(this.Font, FontStyle.Regular); } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // 原有的边框绘制代码... // 绘制占位符文本 if (_isPlaceholder && !string.IsNullOrEmpty(_placeholderText)) { using (Brush brush = new SolidBrush(_placeholderColor)) { e.Graphics.DrawString(_placeholderText, this.Font, brush, new PointF(this.Padding.Left, (this.Height - this.Font.Height) / 2)); } } } ``` ### 添动画效果 ```csharp // 在CustomTextBox类中添以下代码 private Timer _focusTimer; private int _animationProgress = 0; private const int ANIMATION_DURATION = 15; // 毫秒 public CustomTextBox() { // 构造函数中初始化定时器 _focusTimer = new Timer(); _focusTimer.Interval = ANIMATION_DURATION; _focusTimer.Tick += FocusTimer_Tick; } private void FocusTimer_Tick(object sender, EventArgs e) { if (_isFocused && _animationProgress < 100) { _animationProgress += 5; this.Invalidate(); } else if (!_isFocused && _animationProgress > 0) { _animationProgress -= 5; this.Invalidate(); } else { _focusTimer.Stop(); } } protected override void OnGotFocus(EventArgs e) { base.OnGotFocus(e); _isFocused = true; _focusTimer.Start(); } protected override void OnLostFocus(EventArgs e) { base.OnLostFocus(e); _isFocused = false; _focusTimer.Start(); } // 修改OnPaint方法中的边框绘制部分 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // ...其他代码 // 使用动画进度混合颜色 Color currentBorderColor = Color.FromArgb( (int)(_borderColor.R + (_borderFocusColor.R - _borderColor.R) * _animationProgress / 100f), (int)(_borderColor.G + (_borderFocusColor.G - _borderColor.G) * _animationProgress / 100f), (int)(_borderColor.B + (_borderFocusColor.B - _borderColor.B) * _animationProgress / 100f)); // 使用currentBorderColor绘制边框... } ``` ## 设计注意事项 1. **性能优化**: - 只在必要时调用`Invalidate()`方法重绘控件 - 使用`using`语句确保绘图资源及时释放 - 避免在绘制方法中创建大量临时对象 2. **兼容性考虑**: - 测试不同DPI设置下的显示效果 - 确保在高对比度模式下仍可正常使用 - 支持Windows经典主题和现代主题 3. **键盘导航**: - 确保Tab键顺序正常工作 - 支持Ctrl+A全选等标准快捷键 - 正确处理Enter键事件 这种自定义TextBox控件实现方法完全基于.NET Framework,无需第三方库,通过重写控件行为和绘制逻辑实现了高度可定制的边框样式[^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值