3. 使用UIKit构建基础界面

使用UIKit构建基础界面 学习卡片

任务说明

本案例要求使用UIKit框架,以纯代码方式(不使用Storyboard)构建一个基础的用户登录界面。界面需包含:用户名输入框、密码输入框、登录按钮以及一个用于显示提示信息的标签。目标是通过此案例掌握UIKit核心控件的创建、Auto Layout约束配置以及视图控制器的生命周期管理。

界面布局设计

界面采用垂直布局,从上到下依次为:应用标题标签、用户名输入框、密码输入框、登录按钮、状态提示标签。所有控件均使用Auto Layout进行约束,确保在不同尺寸的iPhone设备上都能正确显示。输入框使用圆角边框样式,密码输入框开启安全文本输入模式。

9:41 登录 欢迎使用 用户名 密码 登 录 提示:请输入用户名和密码 (初始状态) 30 70

代码实现

创建 LoginViewController.swift 文件,完整实现登录界面的构建与交互逻辑。代码采用纯代码方式,在 viewDidLoad 中完成所有子视图的添加与约束配置。


import UIKit

class LoginViewController: UIViewController {
    
    // MARK: - UI 组件
    private let titleLabel: UILabel = {
        let label = UILabel()
        label.text = "欢迎使用"
        label.font = UIFont.systemFont(ofSize: 24, weight: .bold)
        label.textColor = .label
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let usernameTextField: UITextField = {
        let textField = UITextField()
        textField.placeholder = "请输入用户名"
        textField.borderStyle = .roundedRect
        textField.backgroundColor = .systemBackground
        textField.autocapitalizationType = .none
        textField.translatesAutoresizingMaskIntoConstraints = false
        return textField
    }()
    
    private let passwordTextField: UITextField = {
        let textField = UITextField()
        textField.placeholder = "请输入密码"
        textField.borderStyle = .roundedRect
        textField.backgroundColor = .systemBackground
        textField.isSecureTextEntry = true
        textField.translatesAutoresizingMaskIntoConstraints = false
        return textField
    }()
    
    private let loginButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("登 录", for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .systemBlue
        button.layer.cornerRadius = 22
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()
    
    private let statusLabel: UILabel = {
        let label = UILabel()
        label.text = "提示:请输入用户名和密码"
        label.font = UIFont.systemFont(ofSize: 14)
        label.textColor = .systemOrange
        label.textAlignment = .center
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    // MARK: - 视图生命周期
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemGroupedBackground
        setupUI()
        setupConstraints()
        loginButton.addTarget(self, action: #selector(loginButtonTapped), for: .touchUpInside)
    }
    
    // MARK: - UI 搭建
    private func setupUI() {
        view.addSubview(titleLabel)
        view.addSubview(usernameTextField)
        view.addSubview(passwordTextField)
        view.addSubview(loginButton)
        view.addSubview(statusLabel)
    }
    
    private func setupConstraints() {
        NSLayoutConstraint.activate([
            // 标题标签:位于安全区域顶部下方 40pt
            titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40),
            titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            titleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 20),
            titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -20),
            
            // 用户名输入框:标题下方 30pt
            usernameTextField.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 30),
            usernameTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40),
            usernameTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -40),
            usernameTextField.heightAnchor.constraint(equalToConstant: 44),
            
            // 密码输入框:用户名下方 16pt
            passwordTextField.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor, constant: 16),
            passwordTextField.leadingAnchor.constraint(equalTo: usernameTextField.leadingAnchor),
            passwordTextField.trailingAnchor.constraint(equalTo: usernameTextField.trailingAnchor),
            passwordTextField.heightAnchor.constraint(equalToConstant: 44),
            
            // 登录按钮:密码下方 30pt
            loginButton.topAnchor.constraint(equalTo: passwordTextField.bottomAnchor, constant: 30),
            loginButton.leadingAnchor.constraint(equalTo: usernameTextField.leadingAnchor),
            loginButton.trailingAnchor.constraint(equalTo: usernameTextField.trailingAnchor),
            loginButton.heightAnchor.constraint(equalToConstant: 44),
            
            // 状态标签:按钮下方 20pt
            statusLabel.topAnchor.constraint(equalTo: loginButton.bottomAnchor, constant: 20),
            statusLabel.leadingAnchor.constraint(equalTo: usernameTextField.leadingAnchor),
            statusLabel.trailingAnchor.constraint(equalTo: usernameTextField.trailingAnchor)
        ])
    }
    
    // MARK: - 按钮点击事件
    @objc private func loginButtonTapped() {
        guard let username = usernameTextField.text, !username.isEmpty,
              let password = passwordTextField.text, !password.isEmpty else {
            statusLabel.text = "错误:用户名和密码不能为空"
            statusLabel.textColor = .systemRed
            return
        }
        
        // 此处仅演示UI交互,实际登录验证需对接后端服务
        statusLabel.text = "登录成功,欢迎:\(username)"
        statusLabel.textColor = .systemGreen
    }
}

落地与运行方式

本案例代码需在Xcode工程中使用。创建步骤:

  1. 打开Xcode,创建新工程,选择 iOS App 模板;
  2. 在 Interface 选项中选择 Swift,Interface 选择 Storyboard(仅用于生成工程骨架);
  3. 删除默认生成的 ViewController.swift 中的内容,替换为上述完整代码;
  4. 打开 Info.plist 或工程设置,确保 Main storyboard file base name 为空;
  5. 在 AppDelegate.swift 的 didFinishLaunchingWithOptions 中设置根视图控制器:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = LoginViewController()
    window?.makeKeyAndVisible()
    return true
}

运行工程(⌘R),模拟器或真机将显示登录界面。

验证方法与判定标准

完成上述步骤后,按以下路径验证:

  • 界面显示验证:启动应用后,应看到标题、两个输入框、蓝色登录按钮和状态标签,各控件间距与SVG示意图一致;
  • 空值校验验证:不输入任何内容直接点击登录按钮,状态标签文字变为红色“错误:用户名和密码不能为空”;
  • 正常登录验证:输入用户名 testuser 和任意非空密码,点击登录按钮,状态标签变为绿色“登录成功,欢迎:testuser”;
  • 安全输入验证:在密码框输入时,字符显示为圆点而非明文;
  • 键盘类型验证:点击用户名输入框时,系统键盘不自动大写首字母。

以上5项全部符合预期,即判定本案例实现通过。注意:本案例仅演示UIKit界面构建与基础交互,不包含真实网络登录验证。