4

I've an app that consists of a timetable (UITableView) and a daybar (UICollectionView). The user can change their selected day by one of two methods:

  1. Select a day from the DayBar
  2. Click the "JumpToTomorrow" Button at the bottom of the table view.

The problem with 2. right now is that when I click it in a scenario where the next day has not yet been scrolled on to the screen, the cell for that day is not selected (see below). enter image description here

DayCollectionViewCell.isSelected (not being called for some reason)

    override var isSelected: Bool {
    didSet {
        self.backgroundColor        = self.getBackgroundColor(selected: isSelected)
        self.layer.borderColor      = self.getBorderColor(selected: isSelected)
        self.number.attributedText  = NSAttributedString(string: number.text!, attributes: self.getTextAttributes(selected: isSelected))
    }
}

DayBarController Functions

    override func viewDidLoad() {
    super.viewDidLoad()
    // To preserve selection between presentations
    self.clearsSelectionOnViewWillAppear = false
    setEdgeInsets()
    BroadcastManager.listen(to: PrepNotifications.JumpToTomorrowClicked, listenerId: "UpdateSelectedDay", react: updateSelectedDay)
}
    /// change the selected day and notify the app about the change
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    PrepGlobals.Calendar.SELECTED_DAY = indexPath.row
    BroadcastManager.broadcast(PrepNotifications.SelectedDayChanged)
    //scroll to center on selected day in case of clicked on today  
    if (PrepGlobals.Calendar.TODAY_INDEX == indexPath.row){
        self.collectionView?.scrollToItem(
            at: indexPath,
            at: .centeredHorizontally,
            animated: true
        )
    }
}

private func updateSelectedDay(_ userInfo: [AnyHashable: Any]? = nil) {
    PrepGlobals.Calendar.SELECTED_DAY += 1
    let selectedDayIndex = IndexPath(row: PrepGlobals.Calendar.SELECTED_DAY, section: 0)
    self.collectionView!.selectItem(at: selectedDayIndex, animated: true, scrollPosition: .right)
    BroadcastManager.broadcast(PrepNotifications.SelectedDayChanged)
}
Declan McKenna
  • 4,321
  • 6
  • 54
  • 72

3 Answers3

1

You should modify your collectionView(_:cellForItemAt:) to check the cell index should be selected or not and update the style there.

Morty Choi
  • 2,466
  • 1
  • 18
  • 26
  • This doesn't appear to be called for the cell I need. In the example pictured within my question `collectionView(_cellForItemAt)` is called for the cells 5 and 7. When we're looking to change the selection from 5 to 6. – Declan McKenna Jun 01 '17 at 11:57
  • Looks like prefetching causes this to be called prior to it appearing on the screen or being set to `selected`. – Declan McKenna Jun 01 '17 at 13:15
1

I edited my answer. Actually you have to set up isSelected manually.

override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
      cell.isSelected = (indexPath.row == PrepGlobals.Calendar.SELECTED_DAY)
}
PMT
  • 1,082
  • 8
  • 18
1

Disabling Pre-fetching fixed this.

enter image description here

Declan McKenna
  • 4,321
  • 6
  • 54
  • 72