[英]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
發送用戶的操作時,必須通過具有UITableView
的cellForRowAt
委托方法的UIViewController
接收它。 為了查看用戶選擇了哪個segmentControl,可以設置標簽(e)。 閉包(f)在返回cell
之前設置。 您可以在閉包內部打印結果。 如果要從委托方法中取出結果,請參見(g)和(h)。
警告
如果您仔細看一下第(e)行, indexPath.row
將用作標記。 僅當您知道沒有刪除任何表行時,此方法才有效。 否則,您的表數據必須具有一個字典值,該值必須為每行賦予唯一的編號。
測試
看看它怎么運作。 當用戶在第二行上使用細分控件時,您將通過cellForRowAt
收到呼叫。 結果是2和1,行中為2, selectedSegmentIndex
值中為1。 用戶不必選擇任何表行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.