簡體   English   中英

通知不適用於UISegmentController

[英]Notification is not working for UISegmentController

我有一個tableView。 我將單元格注冊如下:

tableView.register(TVCellElementProperties.self, forCellReuseIdentifier: cellId1)

TVCellElementProperties內部,我手動創建了一個分段控制器,如下所示:

    let unitTypeSegmentedControl: UISegmentedControl = {
    let types = ["Blue", "White"]
    let sc = UISegmentedControl(items: types)
    sc.selectedSegmentIndex = 0
    sc.translatesAutoresizingMaskIntoConstraints = false
    sc.tintColor = UIColor.darkBlue
    sc.addTarget(self, action: #selector(handleUnitChange), for: .valueChanged)

    return sc
}()

@objc func handleUnitChange() {
    NotificationCenter.default.post(name: .unitPicked, object: self)
}

因此,我認為當我更改SegmentController中的值時,它應該將我重定向到功能handleUnitChange()

在tableView內部,我將以下行插入到ViewDidLoad中:

NotificationCenter.default.addObserver(self, selector: #selector(unitPicked), name: .unitPicked, object: nil)

當我運行應用程序時,未調用tableviewCell內部的** handleUnitChange **函數。 我做錯了什么? 我怎么知道我點擊了什么?

編輯:我正在調用setupView函數,該函數負責從UITableViewCell內的init插入Cell內的細分控制器,如下所示:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.setupViews()
    print("test init")
}

因此,當我運行它時,setupView僅被調用一次,因此** handleUnitChange **也僅被調用一次。 我的意思是說,當應用程序啟動並運行時,以及當我單擊TableView內的段控制器時,不再調用function handleUnitChange

我試圖從CellForRow內部的Cell調用函數,但與上面相同。 我在細分控制器中單擊的函數** handleUnitChange **不被稱為超時。

if let cell = tableView.dequeueReusableCell(withIdentifier: cellId1, for: indexPath) as? TVCellElementProperties {

    //cell.backgroundColor = UIColor.rgb(red: 12, green: 122, blue: 12)
    //cell.contentView.isUserInteractionEnabled = false
    cell.setupViews()
    //print("\(cell.handleUnitChange(sender: u))")
    cell.handleUnitChange(sender: cell.unitTypeSegmentedControl)
    return cell
}

第1步

我們首先研究UITableViewCell

class ProfileTableViewCell: UITableViewCell {
    // MARK: - IBOutlet
    @IBOutlet var firstLabel: UILabel!
    @IBOutlet var lastLabel: UILabel!
    @IBOutlet var ageLabel: UILabel!
    @IBOutlet var pictureImageView: UIImageView!
    @IBOutlet weak var segmentControl: UISegmentedControl! // (a)

    // MARK: - awakeFromNib
    override func awakeFromNib() {
        super.awakeFromNib()
        firstLabel.backgroundColor = UIColor.clear
        lastLabel.backgroundColor = UIColor.clear
        ageLabel.backgroundColor = UIColor.clear
        segmentControl.addTarget(self, action: #selector(valueChanged), for: .valueChanged) // (b)
    }

    var onSegmentChanged: ((Int, Int) -> Void)? // (c)

    // (d)
    @objc func valueChanged(sender: UISegmentedControl) {
        onSegmentChanged!(sender.tag, sender.selectedSegmentIndex)
    }
}

首先,通過Interface Builder添加IBOutlet連接(a)。 通過awakFromNib設置選擇器目標(b)。 為了通過UITableView接收用戶的操作,必須發送帶有閉包(c)的信號。 最后,添加目標接收器(c)。

第2步

現在,我們使用UIViewController

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let people = fetchedResultsController.fetchedObjects else { return 0 }
        return people.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ProfileTableViewCell
        let person = fetchedResultsController.object(at: indexPath)
        cell.segmentControl.tag = indexPath.row // (e)
        // action //
        (f)
        cell.onSegmentChanged = { tag, selectedSegment in
            // (g) self.segmentTapped(tag: tag, index: selectedSegment)
            // print(tag, selectedSegment)
        }
        return cell
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // fetching data //
            let person = fetchedResultsController.object(at: indexPath)

            // deleting data //
            person.managedObjectContext?.delete(person)

            // saving the change //
            let context = persistentContainer.viewContext
            do {
                try context.save()
                print("saved...")
            } catch {
                print("failed saving")
            }
        }
    }

    (h)
    func segmentTapped(tag: Int, index: Int) {
        print(tag, index)
    }
}

當您通過UITableViewCell發送用戶的操作時,必須通過具有UITableViewcellForRowAt委托方法的UIViewController接收它。 為了查看用戶選擇了哪個segmentControl,可以設置標簽(e)。 閉包(f)在返回cell之前設置。 您可以在閉包內部打印結果。 如果要從委托方法中取出結果,請參見(g)和(h)。

警告

如果您仔細看一下第(e)行, indexPath.row將用作標記。 僅當您知道沒有刪除任何表行時,此方法才有效。 否則,您的表數據必須具有一個字典值,該值必須為每行賦予唯一的編號。

測試

看看它怎么運作。 當用戶在第二行上使用細分控件時,您將通過cellForRowAt收到呼叫。 結果是2和1,行中為2, selectedSegmentIndex值中為1。 用戶不必選擇任何表行。

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM