Reputation: 11193
I'm trying to pre select a table row when the view load, however i have tried several methods, but none seem to work. At first i've set following two methods in order to define the textColor changes when a row is selected and deselected
open func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = menuCells[indexPath.row]
cell.textLabel?.textColor = UIColor.white.withAlphaComponent(0.4)
}
open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = menuCells[indexPath.row]
cell.textLabel?.textColor = UIColor.white.withAlphaComponent(1.0)
UIApplication.shared.sendAction(cell.menuAction, to: cell.menuTarget, from: cell, for: nil)
}
Then i've tried to do following things to preselect a row but it does not seem to change the textColor with alpha to 1.0
open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
cell.setSelected(true, animated: false)
}
}
menuView.selectRow(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: UITableViewScrollPosition.none)
Upvotes: 1
Views: 2169
Reputation: 1471
I think it's most appropriate to select the row in the viewWillAppear
method as the view must have been fully initialized.
The example below selects the first cell of the first section:
override func viewWillAppear(_ animated: Bool) {
let selectedIndexPath = IndexPath(row: 0, section: 0)
tableView.selectRow(at: selectedIndexPath, animated: true, scrollPosition: UITableViewScrollPosition.none)
tableView(tableView, didSelectRowAt: selectedIndexPath)
}
Upvotes: 0
Reputation: 19281
Remember that tableView(_:didSelectRowAt:)
is part of a delegate protocol designed to handle user interactions with the UITableView
instance. It is therefore called in response to user interaction, not programatic changes.
To resolve this, move your appearance changes into a separate function called something like applyAppearanceSelected
and call this when you make programatic changes, and also call it from tableView(_:didSelectRowAt:)
to handle user-initiated changes. I would not recommend calling tableView(_:didSelectRowAt:)
directly yourself, because you might want to add other code there that only applies when the user selects a cell.
Upvotes: 0
Reputation: 9136
According Apple's documentation:
Calling selectRowAtIndexPath does not cause the delegate to receive a tableView(:willSelectRowAt:) or tableView(:didSelectRowAt:) message
https://developer.apple.com/reference/uikit/uitableview/1614875-selectrowatindexpath
So in viewDidAppear method you should call manually didSelectRowAtIndexPath like in the example below:
class ViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let indexPath = NSIndexPath(forRow: 2, inSection: 0)
myTableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
// Calling manually to the delegate method
tableView(myTableView, didSelectRowAtIndexPath: indexPath)
}
}
// UITableView Delegate Implementation
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell?.textLabel?.textColor = UIColor.blackColor()
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
cell?.textLabel?.textColor = UIColor.redColor()
cell?.textLabel?.backgroundColor = UIColor.clearColor()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = String(indexPath.row)
return cell
}
}
Result:
Upvotes: 2
Reputation: 762
Is this what you're after?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let iPath = NSIndexPath(forRow: 0, inSection: 0)
tableView.selectRowAtIndexPath(iPath, animated: true, scrollPosition: .Top )
}
Upvotes: 1