iOS Button自定义渲染器:背景色过渡与标题色透明度问题
我来帮你搞定这两个按钮自定义渲染的问题,咱们直接针对代码调整:
问题1:为BackgroundColor添加和TitleColor默认一致的过渡动画
你之前的代码是在触摸事件里直接硬切换颜色,还用UIView.PerformWithoutAnimation关掉了TitleColor的动画,这就导致背景色完全没有过渡效果。其实UIKit的按钮状态切换本身就支持平滑动画,咱们可以利用UIView.Animate来实现和系统TitleColor一致的过渡,同时把状态管理理得更清晰:
核心改动点:
- 去掉
PerformWithoutAnimation,恢复TitleColor的默认动画(如果需要保留动画的话) - 用
UIView.Animate包裹背景色的切换,动画时长使用系统默认的UIView.AnimationDuration,保证和TitleColor的动画节奏完全同步 - 把状态更新逻辑抽成统一方法,避免重复代码
问题2:解决聚焦时TitleColor半透明的问题
按钮进入UIControlState.Focused状态时,系统默认会给标题添加半透明效果,咱们只需要显式设置Focused状态下的TitleColor为你想要的不透明颜色,就能覆盖系统的默认行为。
修改后的完整代码:
public class BtnRendereriOS : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); if (Control != null) { Control.Layer.CornerRadius = 0; // 初始化默认状态的颜色 UpdateButtonState(Control, UIControlState.Normal); // 绑定状态变化事件,统一处理所有触摸场景 Control.TouchUpInside += (sender, args) => UpdateButtonState(sender as UIButton, UIControlState.Normal); Control.TouchUpOutside += (sender, args) => UpdateButtonState(sender as UIButton, UIControlState.Normal); Control.TouchDragOutside += (sender, args) => UpdateButtonState(sender as UIButton, UIControlState.Normal); Control.TouchDragInside += (sender, args) => UpdateButtonState(sender as UIButton, UIControlState.Highlighted); Control.TouchDown += (sender, args) => UpdateButtonState(sender as UIButton, UIControlState.Highlighted); // 监听聚焦状态变化 Control.DidUpdateFocus += (sender, args) => { if (args.NextFocusedView == Control) { UpdateButtonState(Control, UIControlState.Focused); } else { UpdateButtonState(Control, UIControlState.Normal); } }; } } private void UpdateButtonState(UIButton button, UIControlState state) { // 使用系统默认动画时长,保证和TitleColor动画节奏一致 UIView.Animate(UIView.AnimationDuration, () => { switch (state) { case UIControlState.Normal: case UIControlState.Focused: // 聚焦状态复用正常状态的标题色,避免半透明 button.SetTitleColor(UIColor.FromRGB(255,255,255), state); button.BackgroundColor = UIColor.FromRGB(3, 169, 244); break; case UIControlState.Highlighted: button.SetTitleColor(UIColor.FromRGB(0,0,0), state); button.BackgroundColor = UIColor.FromRGB(104, 206, 253); break; } }); } }
关键说明:
- 动画同步:通过
UIView.Animate和系统默认时长,让背景色的过渡动画和TitleColor的默认动画完全匹配,实现统一的视觉效果。 - 聚焦问题解决:显式给
UIControlState.Focused状态设置不透明的标题色,直接覆盖系统默认的半透明效果。 - 代码优化:把状态更新逻辑封装成独立方法,后续修改颜色或新增状态时会更便捷。
内容的提问来源于stack exchange,提问作者Jeppe Christensen
相关产品推荐
相关产品推荐

