我正在创建一个用于访问应用中设置的视图,该视图将显示在UITableView
中。有些单元格会有一个UITableViewCellAccessoryDisclosureIndicator
,我需要一个UISwitch
,另一个单元格的UISegmentedControl类似:
换句话说,我想我需要自定义单元格。通过大量的研究,我已经非常接近,但我无法将我学到的所有东西连接在一起。这就是我所做的:
创建了三个UITableViewCell类:
class DisclosureCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
class SegmentedControlCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
class SwitchCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func defaultIdentifier() -> String {
return NSStringFromClass(self)
}
}
我有我的Sections类和Section结构,它将提供表视图部分和每个可用选项:
class SettingsData {
func getSectionsFromData() -> [Section] {
var settings = [Section]()
let preferences = Section(title: "OPTIONS", objects: ["Formulas", "Lifts", "Units", "Allow 15 reps"])
let patronFeatures = Section(title: "PATRON FEATURES", objects: ["Support OneRepMax"])
let feedback = Section(title: "FEEDBACK", objects: ["Send Feedback", "Please Rate OneRepMax"])
settings.append(preferences)
settings.append(patronFeatures)
settings.append(feedback)
return settings
}
}
struct Section {
var sectionHeading: String
var items: [String]
init(title: String, objects: [String]) {
sectionHeading = title
items = objects
}
}
最后,我的UITableViewController
:
class SettingsViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.topItem?.title = "Settings"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(self.dismissSettings(_:)))
}
func dismissSettings(sender: AnyObject?) {
self.dismissViewControllerAnimated(true, completion: nil)
}
// MARK: - Table view data source
var sections: [Section] = SettingsData().getSectionsFromData()
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].items.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].sectionHeading
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DisclosureCell", forIndexPath: indexPath)
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
我认为我需要帮助的是:
func defaultIdentifier() -> String
,并在Storyboard中为每个单元格类型指定了重用标识符。我需要同时做两件事吗?我发现了很多关于这个主题的帖子,但要么是在Objective-C中,要么他们没有说出我似乎被困在的特定部分。
谢谢!
更新
我已更新我的override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
,如下所示:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = tableView.cellForRowAtIndexPath(indexPath)?.reuseIdentifier
if cellIdentifier == "DisclosureCell" {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "DisclosureCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
} else if cellIdentifier == "SegmentedControlCell" {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "SegmentedControlCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
else {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "SwitchCell")
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
}
我希望这是朝着正确方向迈出的一步,但我仍然遗漏了一些东西,因为我收到了这个错误:
2016-07-28 07:15:35.894 One Rep Max [982:88043] 由于未捕获的异常“NSRangeException”而终止应用,原因如下: ' - [__ NSArrayI objectAtIndex:]:索引2超出界限[0 .. 0]'
我需要找出一种方法让每个单元格知道它应该是哪三种类型,然后根据它的类型,我可以在上面的代码中设置它。
更新2
我现在已经使用indexPath.row
:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as! CustomTableViewCell
if indexPath.row == 0 {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
} else if indexPath.row == 1 {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
//cell.accessoryView = useAuthenticationSwitch
let switchView: UISwitch = UISwitch()
cell.accessoryView = switchView
switchView.setOn(false, animated: false)
return cell
} else {
cell.selectionStyle = .None
cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
let segmentedControl: UISegmentedControl = UISegmentedControl(items: ["lbs", "kg"])
segmentedControl.selectedSegmentIndex = 0
segmentedControl.addTarget(self, action: nil, forControlEvents: .ValueChanged)
cell.accessoryView = segmentedControl
return cell
}
}
问题是,使用indexPath.row
时,并非所有行都具有正确的accessoryView
。在上面的示例中,我希望前两行包含disclosureIndicators
,第三行包含UISegmentedControl
,第四行包含UISwitch
。现在,我完全理解为什么我的代码产生了这个 - 这是因为accessoryView
由单元格的位置决定。相反,我希望能够告诉每个单元格正在创建,“你是这个设置的单元格,所以你得到[填空] accessoryView
”。我为每种类型创建了自定义单元格类,并试图做我正在尝试做的事情,但无法弄明白。您可能会注意到,在上面的代码中,我转到了一个自定义单元类并重用标识符。
我想我可以做if indexPath.row == 0 | 1 { blah, blah }
之类的事情,但这种方法不会贯穿每个section
。如果我尝试像这样处理每个section
,那么代码将变得比现在更加混乱。必须有一个更聪明的方式。
有吗?
答案 0 :(得分:0)
我建议你使用静态单元格(不是原型)来设置这样的屏幕。 您可以在故事板中更改单元格类型。 在将IBOutlets分配给所有控件并使它们与模型交互之后。