You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键说明:

  1. 动画同步:通过UIView.Animate和系统默认时长,让背景色的过渡动画和TitleColor的默认动画完全匹配,实现统一的视觉效果。
  2. 聚焦问题解决:显式给UIControlState.Focused状态设置不透明的标题色,直接覆盖系统默认的半透明效果。
  3. 代码优化:把状态更新逻辑封装成独立方法,后续修改颜色或新增状态时会更便捷。

内容的提问来源于stack exchange,提问作者Jeppe Christensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:42:42