You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS中如何通过编程方式更改键盘样式?附当前与期望样式截图

嘿,针对你想在iOS上修改键盘样式的需求,我整理了两种常见的实现思路,对应不同的场景:

一、调整系统键盘的基础外观(小改动场景)

如果你的期望样式只是修改系统键盘的颜色、色调这类基础属性,不需要完全重构布局,那直接利用UIKit提供的系统API就可以搞定:

1. 修改键盘的明暗风格

通过UITextInputTraits协议的keyboardAppearance属性,可以设置系统键盘为浅色、深色或者跟随系统外观:

// 给单个输入框设置深色键盘
textField.keyboardAppearance = .dark

// 跟随系统的明暗模式(iOS 13+)
textField.keyboardAppearance = .default

2. 修改键盘按钮的高亮颜色

键盘上的输入光标、按钮点击高亮颜色,会继承输入控件的tintColor属性:

// 单个输入框的键盘高亮色设为蓝色
textField.tintColor = .systemBlue

// 全局设置(影响所有系统键盘)
UIView.appearance().tintColor = .systemOrange

二、完全自定义键盘(大改动场景)

如果你的期望键盘和系统键盘布局、样式差异很大(比如自定义按钮形状、特殊功能键、专属主题),那需要创建一个自定义的UIView作为输入控件的键盘:

步骤1:创建自定义键盘视图

先写一个继承自UIView的自定义键盘类,实现布局和按钮点击逻辑:

import UIKit

// 定义代理协议,处理键盘输入事件
protocol CustomKeyboardDelegate: AnyObject {
    func keyboardDidTapCharacter(_ character: String)
    func keyboardDidTapBackspace()
    func keyboardDidTapReturn()
}

class CustomKeyboardView: UIView {
    weak var delegate: CustomKeyboardDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupKeyboardLayout()
        backgroundColor = .systemGray6 // 设置键盘背景色
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 搭建键盘布局,这里用StackView做示例
    private func setupKeyboardLayout() {
        let keyRows = [
            ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
            ["A", "S", "D", "F", "G", "H", "J", "K", "L"],
            ["Z", "X", "C", "V", "B", "N", "M", "⌫"],
            ["123", " ", "↵"]
        ]
        
        let mainStack = UIStackView()
        mainStack.axis = .vertical
        mainStack.spacing = 8
        mainStack.translatesAutoresizingMaskIntoConstraints = false
        addSubview(mainStack)
        
        // 约束主StackView到键盘边缘
        NSLayoutConstraint.activate([
            mainStack.topAnchor.constraint(equalTo: topAnchor, constant: 8),
            mainStack.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
            mainStack.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
            mainStack.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8)
        ])
        
        // 遍历每一行创建按钮
        for row in keyRows {
            let rowStack = UIStackView()
            rowStack.axis = .horizontal
            rowStack.spacing = 6
            rowStack.distribution = .fillEqually
            
            for key in row {
                let keyButton = UIButton(type: .system)
                keyButton.setTitle(key, for: .normal)
                keyButton.titleLabel?.font = .systemFont(ofSize: 18, weight: .medium)
                keyButton.backgroundColor = .white
                keyButton.layer.cornerRadius = 8
                keyButton.addTarget(self, action: #selector(keyTapped(_:)), for: .touchUpInside)
                
                // 给特殊按键设置不同样式
                switch key {
                case "⌫":
                    keyButton.setImage(UIImage(systemName: "delete.left"), for: .normal)
                    keyButton.setTitle(nil, for: .normal)
                case "↵":
                    keyButton.setTitle("Return", for: .normal)
                    keyButton.backgroundColor = .systemBlue
                    keyButton.setTitleColor(.white, for: .normal)
                default:
                    break
                }
                
                rowStack.addArrangedSubview(keyButton)
                // 固定按钮高度
                keyButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
            }
            
            mainStack.addArrangedSubview(rowStack)
        }
    }
    
    // 处理按钮点击事件
    @objc private func keyTapped(_ sender: UIButton) {
        guard let keyText = sender.title(for: .normal) else {
            delegate?.keyboardDidTapBackspace()
            return
        }
        
        switch keyText {
        case "⌫":
            delegate?.keyboardDidTapBackspace()
        case "↵":
            delegate?.keyboardDidTapReturn()
        case "123":
            // 这里可以扩展切换数字键盘的逻辑
            print("切换到数字键盘")
        default:
            delegate?.keyboardDidTapCharacter(keyText)
        }
    }
}

步骤2:将自定义键盘绑定到输入控件

在ViewController中,把自定义键盘赋值给输入控件的inputView属性,并实现代理方法处理输入:

class ViewController: UIViewController, CustomKeyboardDelegate {
    private let customTextField = UITextField()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTextField()
    }
    
    private func setupTextField() {
        customTextField.borderStyle = .roundedRect
        customTextField.placeholder = "试试自定义键盘"
        customTextField.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(customTextField)
        
        // 创建自定义键盘并绑定代理
        let customKeyboard = CustomKeyboardView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 250))
        customKeyboard.delegate = self
        customTextField.inputView = customKeyboard
        
        // 布局输入框
        NSLayoutConstraint.activate([
            customTextField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            customTextField.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            customTextField.widthAnchor.constraint(equalToConstant: 300)
        ])
    }
    
    // MARK: - CustomKeyboardDelegate 实现
    func keyboardDidTapCharacter(_ character: String) {
        customTextField.insertText(character)
    }
    
    func keyboardDidTapBackspace() {
        customTextField.deleteBackward()
    }
    
    func keyboardDidTapReturn() {
        customTextField.resignFirstResponder()
        view.endEditing(true)
    }
}

额外注意点

  1. 适配不同设备:自定义键盘的高度可以根据屏幕尺寸调整,或者监听UIKeyboardWillShowNotification获取系统键盘的高度,保持和系统键盘一致;
  2. 避免私有API:不要尝试通过私有API修改系统键盘的内部布局,会导致App被拒;
  3. 多输入控件共享:如果多个输入框要使用同一个自定义键盘,可以把键盘实例复用,或者封装成全局工具类。

内容的提问来源于stack exchange,提问作者Pathak Ayush

火山引擎 最新活动