iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
Mobile Development

我將成為Swift之強者系列 第 6

Day 6 -調色盤實作Final(XIB 與程式碼連結)

  • 分享至 

  • xImage
  •  

Day 6 - 調色盤實作(XIB 與程式碼連結)

昨天我們完成了 XIB 介面的元件擺放與約束,今天要進一步將 XIB 與程式碼做連結,讓使用者能夠透過 Slider 與 TextField 控制顏色變化。

首先點擊右上角的增加視窗

https://ithelp.ithome.com.tw/upload/images/20250920/20178625G4MjgCyTCN.png

看你哪一個視窗需要Xib或者Swift(程式碼)頁面在各自點選就可以了

https://ithelp.ithome.com.tw/upload/images/20250920/2017862587P6lRBAxy.png

點選需要連結的元件,按住 Control,拖曳到程式碼頁面即可建立連結。

(抱歉用手機拍,因截圖會卡快捷鍵)
https://ithelp.ithome.com.tw/upload/images/20250920/20178625eeYeX0pnRG.jpg

命名規則建議依照功能命名,例如 sldRedValue, lbRed,確保清楚明瞭。

⚠️提醒:一定要用拖曳方式建立連結,不能手動複製貼上,否則 Xcode 無法正確辨識。

https://ithelp.ithome.com.tw/upload/images/20250920/20178625WmM9hzculy.png


IBOutlet 宣告

以下是 XIB 與程式碼連結後的 IBOutlet 範例:

@IBOutlet weak var vRGB: UIView!
@IBOutlet weak var sldRedValue: UISlider!
@IBOutlet weak var sldGreenValue: UISlider!
@IBOutlet weak var sldBlueValue: UISlider!
@IBOutlet weak var lbRed: UILabel!
@IBOutlet weak var lbGreen: UILabel!
@IBOutlet weak var lbBlue: UILabel!
@IBOutlet weak var txfRedText: UITextField!
@IBOutlet weak var txfGreenText: UITextField!
@IBOutlet weak var txfBlueText: UITextField!

這些屬性會對應到我們在 XIB 畫面上配置的 UI 元件,接下來就能在程式碼中操作它們。


完整程式碼與講解

LifeCycle – viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    txfRedText.delegate = self
    txfGreenText.delegate = self
    txfBlueText.delegate = self
}
  • 設定三個 TextField 的委派為 self,確保能透過 UITextFieldDelegate 來處理輸入。

Slider 事件處理

@IBAction func changeSlider(_ sender: UISlider) {
    let redValue = Int(sldRedValue.value)
    let greenValue = Int(sldGreenValue.value)
    let blueValue = Int(sldBlueValue.value)

    lbRed.text = "\(redValue)"
    lbGreen.text = "\(greenValue)"
    lbBlue.text = "\(blueValue)"

    txfRedText.text = "\(redValue)"
    txfGreenText.text = "\(greenValue)"
    txfBlueText.text = "\(blueValue)"

    vRGB.backgroundColor = UIColor(
        red: CGFloat(redValue) / 255.0,
        green: CGFloat(greenValue) / 255.0,
        blue: CGFloat(blueValue) / 255.0,
        alpha: 1.0
    )
}
  • 當使用者拖曳 Slider 時觸發。
  • 取得三個顏色數值,更新 Label 與 TextField。
  • 使用 UIColor 更新顏色預覽區塊 vRGB

TextField 輸入處理

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()

    let redValue = Int(txfRedText.text ?? "") ?? 0
    let greenValue = Int(txfGreenText.text ?? "") ?? 0
    let blueValue = Int(txfBlueText.text ?? "") ?? 0

    sldRedValue.value = Float(redValue)
    sldGreenValue.value = Float(greenValue)
    sldBlueValue.value = Float(blueValue)

    lbRed.text = "\(redValue)"
    lbGreen.text = "\(greenValue)"
    lbBlue.text = "\(blueValue)"

    vRGB.backgroundColor = UIColor(
        red: CGFloat(redValue) / 255.0,
        green: CGFloat(greenValue) / 255.0,
        blue: CGFloat(blueValue) / 255.0,
        alpha: 1.0
    )
    return true
}
  • 當使用者在輸入框輸入數字並按下 Return 鍵時觸發。
  • 將輸入的數字更新到 Slider 與 Label。
  • 重新繪製顏色,保持顯示區塊與輸入同步。

小結

今天我們完成了:

  1. XIB 與程式碼的 IBOutlet 連結
  2. Slider 控制顏色變化
  3. TextField 與 Slider 的數值互動

透過這樣的流程,介面上的數值變動能即時反映在顏色顯示區,建立一個簡單的 RGB 調色盤。


完整程式碼

//
//  MainViewController.swift
//  Color Palette
//
//  Created by imac-2627 on 2025/7/4.
//

import UIKit

class MainViewController: UIViewController, UITextFieldDelegate {
    
    // MARK: - IBOutlet
    
    @IBOutlet weak var vRGB: UIView!
    @IBOutlet weak var sldRedValue: UISlider!
    @IBOutlet weak var sldGreenValue: UISlider!
    @IBOutlet weak var sldBlueValue: UISlider!
    @IBOutlet weak var lbRed: UILabel!
    @IBOutlet weak var lbGreen: UILabel!
    @IBOutlet weak var lbBlue: UILabel!
    @IBOutlet weak var txfRedText: UITextField!
    @IBOutlet weak var txfGreenText: UITextField!
    @IBOutlet weak var txfBlueText: UITextField!
    
    // MARK: - Property
    
    // MARK: - LifeCycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        txfRedText.delegate = self
        txfGreenText.delegate = self
        txfBlueText.delegate = self
        setupUI()
    }
    
    // MARK: - UI Setting
    func setupUI() {
        // 初始化UI元件
        updateColorView()
    }
    
    // MARK: - IBAction
    // vRGB 顏色控制
    @IBAction func updateColorView(_ sender: Any) {
        vRGB.backgroundColor = UIColor(
            // 正確將 0-255 的值轉換為 0-1 的範圍
            red: CGFloat(sldRedValue.value) / 255.0,
            green: CGFloat(sldGreenValue.value) / 255.0,
            blue: CGFloat(sldBlueValue.value) / 255.0,
            alpha: 1
        )
    }
    
    // slider
    @IBAction func sliderToText(_ sender: UISlider) {
        // 紅綠藍三個顏色數值的顯示,顯示在 TextField
        txfRedText.text = "\(Int(sldRedValue.value))"
        txfGreenText.text = "\(Int(sldGreenValue.value))"
        txfBlueText.text = "\(Int(sldBlueValue.value))"

        // 呼叫 View,將 Slider 的值傳入 vRGB 讓他顯示顏色
        updateColorView(sender)
    }
    
    // 會有三個部分一樣邏輯的 Code 來分別控制三種顏色
    @IBAction func textToSlider(_ sender: UITextField) {
        // 紅色
        if let redStringValue = txfRedText.text {
            // 限制輸入的值只能用數字
            if let redIntValue = Int(redStringValue) {
                // 限制最高255,超過255會自動變成255,最低0
                let redValue = max(0, min(255, redIntValue))
                sldRedValue.setValue(Float(redValue), animated: true)
                txfRedText.text = "\(redValue)"
            } else {
                // 如果不是數字的話會自動歸0
                sldRedValue.setValue(0, animated: true)
                txfRedText.text = "0"
            }
        } else {
            // 沒有輸入值的話也是0
            sldRedValue.setValue(0, animated: true)
        }

        // 綠色
        if let greenStringValue = txfGreenText.text {
            // 限制輸入的值只能用數字
            if let greenIntValue = Int(greenStringValue) {
                // 限制最高255,超過255會自動變成255,最低0
                let greenValue = max(0, min(255, greenIntValue))
                sldGreenValue.setValue(Float(greenValue), animated: true)
                txfGreenText.text = "\(greenValue)"
            } else {
                // 如果不是數字的話會自動歸0
                sldGreenValue.setValue(0, animated: true)
                txfGreenText.text = "0"
            }
        } else {
            // 沒有輸入值的話也是0
            sldGreenValue.setValue(0, animated: true)
        }

        // 藍色
        if let blueStringValue = txfBlueText.text {
            // 限制輸入的值只能用數字
            if let blueIntValue = Int(blueStringValue) {
                let blueValue = max(0, min(255, blueIntValue))
                sldBlueValue.setValue(Float(blueValue), animated: true)
                txfBlueText.text = "\(blueValue)"
            } else {
                // 如果不是數字的話會自動歸0
                sldBlueValue.setValue(0, animated: true)
                txfBlueText.text = "0"
            }
        } else {
            // 沒有輸入值的話也是0
            sldBlueValue.setValue(0, animated: true)
        }

        // 以上程式執行完之後,呼叫 updateColorView,令 vRGB 做改變
        updateColorView(sender)
    }
    
    // MARK: - Function
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // 令用戶按下 Return(Enter) 鍵時會立即輸入,並隱藏鍵盤
        textField.resignFirstResponder()

        // 在 TextField 輸入值之後 同步我的 Slider
        textToSlider(textField)
        return true
    }
    
    // MARK: - Extensions
    
}


上一篇
Day 5 - 調色盤實作(XIB 介面建立與元件擺放)
下一篇
Day 7 - 留言板實作前置動作:Realm 資料庫部署
系列文
我將成為Swift之強者8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言