【问题标题】:How to create UITextField accessory view iOS7 with appropriate opacity, or even duplicate the keys?如何创建具有适当不透明度的 UITextField 附件视图 iOS7,甚至复制键?
【发布时间】:2026-01-21 23:05:01
【问题描述】:

在 iOS7 中,Apple 将键盘设为半透明(在 iPhone 上)。如果我想添加一个匹配不透明度的附件视图,我该怎么做?另外,我想在附件视图中模仿键盘键 - 我该怎么做?

【问题讨论】:

    标签: ios ios7 uitextfield uitextview


    【解决方案1】:

    UIInputView 在这种情况下不会有任何帮助吗?

    Apple Class Reference 表示以下内容:

    The UIInputView class is designed to match the appearance of the standard system keyboard when used as an input view with a responder. When defining your own custom input views or input accessory views, you can use a UIInputView object as the root view and add any subviews you want to create your input view. The input view and its subviews receive tinting and blur effects based on the options you specify at initialization time.

    【讨论】:

    • 嗯,每天都学点东西!没听说过这种观点。将尽快调查!该课程是 iOS7 的新增功能,但我不记得在 WWDC 上提到过它......
    【解决方案2】:

    在 iOS7 上,手机弹出半透明键盘,但附件视图按原样呈现 - 未应用半透明。因此,如果用户在键盘下方有视图,则用户将看到键盘上有一些流血,但看不到您的附件视图。如何确定要在此处应用的适当不透明度?

    这样做的方法是测量键盘弹出白色背景时背景的变化,然后是黑色背景。但是评估键盘视图中的变化,您可以找出键盘用于背景颜色的内容 - 颜色和不透明度设置。键及其边框等也是如此。

    这就是以下代码的作用——但它的作用更多。它参数化按钮 - 适用于 iPhone、iPad、darkKeyboard(iOS7 的新功能)和 lightKeyboard。

    如果您想复制任一设备的按钮,无论是颜色,您都可以这样做 - 添加到您的附件视图。

    如果您不想费心从代码创建我们自己的项目,您可以在 github 上找到一个 - 搜索 CreateShadowedRoundRectButtonImage - 但如果由于某种原因消失了,代码如下。

    编辑:请注意,经过一些测试,我发现在不模糊视图的不透明度的情况下,可以清楚地显示其下方的文本。现在希望使用下面建议的背景颜色,不透明度设置为 0.8 作为 UIToolbar 中的 barTintColor(半透明=YES)(作为 inputAccessoryView)

    typedef struct { CGFloat whiteColor ; CGFloat opacity; } setting;
    
    typedef struct {
        CGFloat     keyboardBackColor;
        CGFloat     keyBackColor;
        CGFloat     keyShadowColor;
        //CGFloat   keyFontColor;       // not changing in 7.0
    
        CGFloat     altKeyBackColor;
        CGFloat     altKeyShadowColor;
        //CGFloat   altKeyFontColor;    // not changing in 7.0
    } keyboardVariant;
    
    typedef struct {
        setting     keyboardBackSetting;
        setting     keyBackColorSetting;
        setting     keyShadowColorSetting;
    
        setting     altKeyBackColorSetting;
        setting     altKeyShadowColorSetting;
    
    } settings;
    
    static settings whiteKeyboardSettings, blackKeyboardSettings;
    
    static BOOL isIdiomPhone;
    
    @implementation CreateButton
    
    + (void)initialize
    {
        isIdiomPhone = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone;
    
        // Using 'Pixie' observe values of the keyboard with an all white or all black background, to compute white and opacity
        // NOTE: black values must be somewhat smaller than the light ones or you get divide by null
        if(isIdiomPhone) {
            // White Keyboard
            {
                keyboardVariant white = { .87f, .99f, .53f,   .77f, .53f };
                keyboardVariant black = { .65f, .98f, .40f,   .66f, .40f }; // Alt Font was .39 no opacity
                whiteKeyboardSettings = [self defineWithWhiteBackground:white blackBackground:black];
            }
            // Black Keyboard
            {
                keyboardVariant white = { .36f, .55f, .21f,   .42f, .21f };
                keyboardVariant black = { .08f, .35f, .05f,   .20f, .05f }; // Alt Font 1.0
                blackKeyboardSettings = [self defineWithWhiteBackground:white blackBackground:black];
            }
        } else {
            // White Keyboard
            {
                keyboardVariant white = { .82f, .99f, .49f,   .75f, .49f };
                keyboardVariant black = { .81f, .98f, .48f,   .74f, .48f }; // Alt Font 1.0
                whiteKeyboardSettings = [self defineWithWhiteBackground:white blackBackground:black];
            }
            // Black Keyboard
            {
                keyboardVariant white = { .05f, .34f, .03f,   .19f, .03f };
                keyboardVariant black = { .04f, .33f, .02f,   .18f, .02f }; // Alt Font 1.0
                blackKeyboardSettings = [self defineWithWhiteBackground:white blackBackground:black];
            }
        }
    }
    
    + (UIColor *)backgroundColorForType:(UIKeyboardAppearance)type
    {
        setting s = type == UIKeyboardAppearanceLight ? whiteKeyboardSettings.keyboardBackSetting : blackKeyboardSettings.keyboardBackSetting;
        return  [UIColor colorWithRed:s.whiteColor-.01 green:s.whiteColor blue:s.whiteColor+.01 alpha:s.opacity];
    }
    
    + (settings)defineWithWhiteBackground:(keyboardVariant)white blackBackground:(keyboardVariant)black
    {
        settings v;
    
        v.keyboardBackSetting       = [self solveForWhite:white.keyboardBackColor black:black.keyboardBackColor whiteBG:1 blackBG:0];
        v.keyBackColorSetting       = [self solveForWhite:white.keyBackColor black:black.keyBackColor whiteBG:white.keyboardBackColor blackBG:black.keyboardBackColor];
        v.keyShadowColorSetting     = [self solveForWhite:white.keyShadowColor black:black.keyShadowColor whiteBG:white.keyboardBackColor blackBG:black.keyboardBackColor];
    
        v.altKeyBackColorSetting    = [self solveForWhite:white.altKeyBackColor black:black.altKeyBackColor whiteBG:white.keyboardBackColor blackBG:black.keyboardBackColor];
        v.altKeyShadowColorSetting  = [self solveForWhite:white.altKeyShadowColor black:black.altKeyShadowColor whiteBG:white.keyboardBackColor blackBG:black.keyboardBackColor];
    
        return v;
    }
    
    + (setting)solveForWhite:(CGFloat)white black:(CGFloat)black whiteBG:(CGFloat)wBG blackBG:(CGFloat)bBG
    {
        // Solve two equations in two variables:
        //   bBG(1-opacity) + whiteColor*opacity = black
        //   wBG(1-opacity) + whiteColor*opacity = white
    
        if(isIdiomPhone) {
            CGFloat a = black - bBG;
            CGFloat b = white - wBG;
    
            CGFloat colorDiff = (a - b);
            CGFloat backgDiff = (wBG - bBG);
    
            CGFloat opacity = colorDiff / backgDiff;
            opacity = MIN(1, opacity);
            opacity = MAX(0, opacity);
    
            CGFloat whiteColor = b/opacity + wBG;
            whiteColor = MIN(1, whiteColor);
            whiteColor = MAX(0, whiteColor);
            assert(whiteColor);
    
            setting setting;
            setting.opacity = opacity;
            setting.whiteColor = whiteColor;
    
            return setting;
        } else {
            setting setting;
            setting.opacity = 1;
            setting.whiteColor = white;
            return setting;
        }
    }
    
    - (UIImage *)buttonImage:(CGSize)size type:(UIKeyboardAppearance)type
    {
        return [self buttonImage:size type:type isAlt:NO];
    }
    
    - (UIImage *)altButtonImage:(CGSize)size type:(UIKeyboardAppearance)type
    {
        return [self buttonImage:size type:type isAlt:YES];
    }
    
    - (UIImage *)buttonImage:(CGSize)size type:(UIKeyboardAppearance)type isAlt:(BOOL)altButton
    {
        CGFloat cornerRadius = isIdiomPhone ? 4 : 7;
        setting foreSetting, shadowSetting;
    
        if(altButton) {
            foreSetting   = type == UIKeyboardAppearanceLight ? whiteKeyboardSettings.altKeyBackColorSetting : blackKeyboardSettings.altKeyBackColorSetting;
            shadowSetting = type == UIKeyboardAppearanceLight ? whiteKeyboardSettings.altKeyShadowColorSetting : blackKeyboardSettings.altKeyShadowColorSetting;
        } else {
            foreSetting   = type == UIKeyboardAppearanceLight ? whiteKeyboardSettings.keyBackColorSetting : blackKeyboardSettings.keyBackColorSetting;
            shadowSetting = type == UIKeyboardAppearanceLight ? whiteKeyboardSettings.keyShadowColorSetting : blackKeyboardSettings.keyShadowColorSetting;
        }
    
        UIColor *foregroundColor    = [UIColor colorWithRed:foreSetting.whiteColor-.01 green:foreSetting.whiteColor blue:foreSetting.whiteColor+.01 alpha:foreSetting.opacity];
        UIColor *shadowColor        = [UIColor colorWithRed:shadowSetting.whiteColor-.01 green:shadowSetting.whiteColor blue:shadowSetting.whiteColor+.01 alpha:shadowSetting.opacity];
    
        CGRect frame = (CGRect){ {0,0}, size };
    
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);    // NO -> not opaque
    
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetBlendMode(context, kCGBlendModeCopy);
    
        if(isIdiomPhone && altButton) {
            UIColor *altColor = [UIColor colorWithRed:foreSetting.whiteColor+.05 green:foreSetting.whiteColor+.06 blue:foreSetting.whiteColor+.07 alpha:foreSetting.opacity];
            [self drawRoundRectofSize:frame inContext:context color:altColor radius:cornerRadius];
            frame.size.height -= 1;
            frame.origin.y += 1;
            [self drawRoundRectofSize:frame inContext:context color:shadowColor radius:cornerRadius];
        } else {
            [self drawRoundRectofSize:frame inContext:context color:shadowColor radius:cornerRadius];
        }
        frame.size.height -= 1;
        [self drawRoundRectofSize:frame inContext:context color:foregroundColor radius:cornerRadius];
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    
    
    - (void)drawRoundRectofSize:(CGRect)rect inContext:(CGContextRef)context color:(UIColor *)fillColor radius:(CGFloat)radius
    {
        CGContextSetFillColorWithColor(context, fillColor.CGColor);
    
        CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
        CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
        CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
                    radius, M_PI, M_PI / 2, 1); //STS fixed
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
                            rect.origin.y + rect.size.height);
        CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
                    rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
        CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);
        CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
                    radius, 0.0f, -M_PI / 2, 1);
        CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);
        CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
                    -M_PI / 2, M_PI, 1);
    
        CGContextFillPath(context);
    }
    

    【讨论】:

    • 这里可能是 Emoji 键盘的另一种情况——它的 bg 颜色略有不同(至少在 iPhone 上)
    最近更新 更多