2017-02-22 34 views
0

我一直試圖在Swift中首次編寫一個應用程序,並且遇到了使用UITableViews的問題。 我已經創建了一個自定義的可重用單元格,我稱之爲「exerciseCell」,並且有一個UILabel UIImageview和一個UISwitch。可重複使用的tableview單元格互相影響

我的問題是,當我選擇第0行上的開關時,它也打開第3和第6行上的開關。這對每個單元都是一樣的,它們每個影響大約三個單元。 這個tableview的目的是爲了能夠選擇你想要練習列表的練習,但它們都需要能夠獨立選擇。

這裏是小區的代碼:

另外,cellForRow如下

class exerciseCell: UITableViewCell { 

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

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

var cellSelected:Bool = false 

let excersiseLabel: UILabel = { 
    let label = UILabel() 
    label.translatesAutoresizingMaskIntoConstraints = false 
    label.textColor = UIColor.red 
    label.textAlignment = NSTextAlignment.center 
    return label 
}() 
let excersiseImage: UIImageView = { 
    let image = UIImageView() 
    image.backgroundColor = UIColor.blue 
    image.translatesAutoresizingMaskIntoConstraints = false 
    return image 
}() 

let thisSwitch: UISwitch = { 
    let thisSwitch = UISwitch() 
    thisSwitch.isOn = false 
    thisSwitch.translatesAutoresizingMaskIntoConstraints = false 
    return thisSwitch 

}() 

func setupViews() { 
    addSubview(excersiseLabel) 
    addSubview(excersiseImage) 
    addSubview(thisSwitch) 
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["v0": excersiseLabel])) 
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-101-[v0(100)]-101-|", options: .alignAllCenterX, metrics: nil, views: ["v0": excersiseImage])) 
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-120-[v0(100)]-120-|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["v0": thisSwitch])) 

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-12-[v0(30)]-8-[v1(100)]-12-[v2(30)]-12-|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": excersiseLabel, "v1": excersiseImage, "v2": thisSwitch])) 

} 

}:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    var thisCell = UITableViewCell() 

    if tableView == self.tableView { 
     let aCell = tableView.dequeueReusableCell(withIdentifier: "thirdCellID", for: indexPath) as! exerciseCell 
     aCell.excersiseLabel.text = "\(mobility[indexPath.row])" 
     aCell.thisSwitch.tag = indexPath.row 
     thisCell = aCell 
    } 
    return thisCell 

} 

我怎樣才能獲得的細胞自主響應用戶?如果需要澄清,我可以提供更多的代碼。

回答

3

由於單元格被表視圖重用,所以它們不會保留其開關設置。您將需要一個外部結構來跟蹤選定哪些單元格。

這個單元格需要讓你的控制器知道它的開關什麼時候被切換(可能通過委託),在這時你會更新你的(例如)BOOL數組。

然後,在cellForRowAtIndexPath中,您需要一些代碼將正確的值應用到單元格。例如:

cell.switch.isOn = cellSwitchStates[indexPath.row] 
0

這是在uitableviewcell中顯示的常見問題。解決此問題的最佳方法是使用對象配置單元格。

例如,您的情況下,您需要顯示Tableview中的練習列表。 因此,使用布爾變量爲Exercise創建一個模態類(例如var switchState: Bool)。

class Exercise: NSObject { 

    var exerciseName : String? 
    var switchState : Bool = false 

    init (exerciseName : String?,switchState : Bool) { 
     super.init() 
     self.exerciseName = exerciseName 
     self.switchState = switchState 
    } 
} 

然後填充運動對象的默認值switchState假的陣列(例如var exercises : [Exercise])。

然後TableView中numberofrows計數從演習陣列...返回exercises.count採取

cellForRowAt indexPath 採取從演習陣列例如爲:var exercise = exercises[indexpath.row]正確行使的對象,現在我們有正確的對象吧?所以創建自定義單元格內一個方法fun configureCellWith(exercise:Exercise)(在你的情況下電池會aCell) 於是呼從cellForRowAt indexPath這種細胞的方法,並通過我們的工作對象作爲參數

例如:內exerciseCellaCell.configureCellWith(exercise) 和你configureCellWith()方法應該是這樣的

// Write this method within exerciseCell 
func configureCellWith(exercise:Exercise) { 

privateExercise = exercise // privateExercise is a private Variable for exerciseCell so please create private var privateExercise : Exercise in exerciseCell 

thisSwitch.isOn = exercise.switchState 

} 

那麼對於exerciseCell

thisSwitch.addTarget(self, action: Selector("switchTriggered:"), forControlEvents: .ValueChanged); 


func switchTriggered(sender: AnyObject) { 

    let switch = sender as! UISwitch 
    privateExercise.switchState = switch.isOn 

} 

現在一切看起來不錯內的交換機上創建一個動作方法..請做開關ON/OFF第0行並檢查它是否影響其他行。謝謝。

+0

非常感謝@Aby,這已經阻止了他們互相影響,但是如果我在桌面視圖中向下滾動,然後向上滾動,開關將返回到關閉位置。 我可能沒有正確地完成私有變量,它不斷給我錯誤,因爲沒有分配一個exerciseName,所以我剛剛將名稱初始化爲「」。 – EtherCode

+0

我認爲這是因爲switchTriggered方法沒有被識別。我已經在func中放置了一個打印(「觸發開關」),但從未顯示。選擇器樣式是否正確? – EtherCode

相關問題