title: How to optimize UITableViewCell, because my UITableView lags
body: <p>Ok, my <code>UITableView</code> is too complicated for loading. And when paging between <code>UIPageViewController</code>, then it lags, I cannot simply and fast swipe between pages. What is wrong?</p>
  
  <p><strong>How doest it work?</strong></p>
  
  <p>My <code>UIViewController</code> has <code>UITableView</code> with lot of cells. Those view controllers are part of <code>UIPageViewController</code>. Swiping between them... lags.</p>
  
  <p>How can I optimize the app to speed it up?</p>
  
  <p>I discovered that this is because of my <code>UITableViewCell</code>, when no cells, then it is simple... and works like a charm. But when cells are loaded, then it lags.</p>
  
  <p>This is my <code>UITableViewCell</code>:</p>
  
  <p><a href="https://i.stack.imgur.com/RSWAgl.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RSWAgl.png" alt="enter image description here"></a>
  <a href="https://i.stack.imgur.com/5DeKRl.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5DeKRl.png" alt="enter image description here"></a></p>
  
  <p>This is my <code>cellForRow:</code></p>
  
  <pre><code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  
      let address = fetchedResultsController.object(at: indexPath)
      let cell = tableView.dequeueReusableCell(withIdentifier: AddressTableViewCellIdentifier, for: indexPath) as! AddressTableViewCell
  
      cell.configure(with: address)
      cell.isSelectionMode = isSelectionMode
      cell.isSelected = selectedAddresses.contains(address)
  
      return cell
  }
  </code></pre>
  
  <p>and <code>AddressTableViewCell</code>:</p>
  
  <pre>
  class AddressTableViewCell: UITableViewCell {
  
      @IBOutlet private var nameLabel: UILabel!
      @IBOutlet private var emptyButton: UIButton!
      @IBOutlet private var rejectedButton: UIButton!
      @IBOutlet private var dateForLastNoteLabel: UILabel!
      @IBOutlet private var addressNoteLabel: UILabel!
      @IBOutlet private var lastNoteLabel: UILabel!
      @IBOutlet private var returnVisitImageView: AttributedImageView!
      @IBOutlet private var regularDeliveryImageView: AttributedImageView!
      @IBOutlet private var studyImageView: AttributedImageView!
      @IBOutlet private var emailImageView: AttributedImageView!
      @IBOutlet private var phoneNumberImageView: AttributedImageView!
      @IBOutlet private var actionButtonsWidthConstraint: NSLayoutConstraint!
  
      @IBOutlet private var selectViewWidthConstraint: NSLayoutConstraint!
      @IBOutlet private var selectView: AttributedView!
  
      private var address: Address!
  
      var isSelectionMode: Bool = false {
  
          didSet {
  
              emptyButton.isEnabled = !isSelectionMode
              rejectedButton.isEnabled = !isSelectionMode
              selectViewWidthConstraint.constant = isSelectionMode ? 50 : 0
              accessoryType = isSelectionMode ? .none : .disclosureIndicator
          }
      }
  
      override var isSelected: Bool {
  
          didSet {
              selectView.backgroundColor = isSelected ? Settings.shared.currentMode.homeColor : UIColor.clear
          }
      }
  
      //MARK: - Class Methods
  
      //MARK: - Initialization
  
      //MARK: - Deinitialization
  
      //MARK: - Actions
  
      @IBAction func emptyButtonTapped(_ sender: UIButton) {
          save(withStatus: [0, 2].contains(address.status) ? 1 : 0)
      }
  
      @IBAction func rejectButtonTapped(_ sender: UIButton) {
          save(withStatus: [0, 1].contains(address.status) ? 2 : 0)
      }
  
      //MARK: - Open
  
      //MARK: - Internal
  
      func configure(with address: Address) {
  
          self.address = address
  
          let status = AddressStatus(rawValue: address.status)!
  
          addressNoteLabel.text = address.text
          nameLabel.text = address.name
          emptyButton.tintColor = status == .empty ? UIColor.black : UIColor.lightGray.withAlphaComponent(0.4)
          rejectedButton.tintColor = status == .rejected ? UIColor.red : UIColor.lightGray.withAlphaComponent(0.4)
          returnVisitImageView.isHidden = status != .returnVisit
          returnVisitImageView.topImageViewTintColor = Settings.shared.currentMode.homeColor
          regularDeliveryImageView.isHidden = !address.isRegularDelivery
          regularDeliveryImageView.topImageViewTintColor = Settings.shared.currentMode.homeColor
          studyImageView.isHidden = !address.isStudy
          studyImageView.topImageViewTintColor = Settings.shared.currentMode.homeColor
          emailImageView.isHidden = address.email == nil
          emailImageView.topImageViewTintColor = Settings.shared.currentMode.homeColor
          phoneNumberImageView.topImageViewTintColor = Settings.shared.currentMode.homeColor
          phoneNumberImageView.isHidden = address.phoneNumber == nil
  
          dateForLastNoteLabel.text = nil
          lastNoteLabel.text = nil
          actionButtonsWidthConstraint.constant = [AddressStatus.returnVisit, ].contains(status) || address.isStudy || address.isRegularDelivery ? 0 : 100
  
          if !returnVisitImageView.isHidden && address.lastNote == nil {
              dateForLastNoteLabel.text = "  "
          }
  
          if let note = address.lastNote {
  
              dateForLastNoteLabel.text = note.descriptiveDateAndTime
              lastNoteLabel.text = note.text
          }
      }
  
      //MARK: - Private
  
      private func save(withStatus status: Int16) {
  
          emptyButton.isEnabled = false
          rejectedButton.isEnabled = false
  
          MagicalRecord.save({ [weak self] context in
  
              self?.address.mr_(in: context)?.status = status
  
          }) { [weak self] _, error in
  
              guard let `self` = self else {
                  return
              }
  
              UIAlertController.show(from: error)
  
              if error == nil {
  
                  Sync.saveForSync(identifier: self.address.identifier, reason: 1)
                  CloudAssistant.shared.performSyncing()
              }
  
              self.emptyButton.isEnabled = true
              self.rejectedButton.isEnabled = true
          }
      }
  
      //MARK: - Overridden
  }
  </pre>