2
votes

Ok, my UITableView is too complicated for loading. And when paging between UIPageViewController, then it lags, I cannot simply and fast swipe between pages. What is wrong?

How doest it work?

My UIViewController has UITableView with lot of cells. Those view controllers are part of UIPageViewController. Swiping between them... lags.

How can I optimize the app to speed it up?

I discovered that this is because of my UITableViewCell, when no cells, then it is simple... and works like a charm. But when cells are loaded, then it lags.

This is my UITableViewCell:

enter image description here enter image description here

This is my cellForRow:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 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
}

and AddressTableViewCell:

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
}
1
What code do you have in cellForRowAtIndexPath? The issue is almost certainly not UI-related, but logic/API call related.Connor Neville
Everything is fetched from NSFRC and data is assigned to labels and some icons.Bartłomiej Semańczyk
The cell has a lot of UI elements that is recalculate it's constraints every time the cellForRow method called , try to remove the stack views , and work it out without them.Ayman Ibrahim
Ok, I try and let you know... how does it work then...Bartłomiej Semańczyk
I suggest profiling the app with the Time Profiler.D. Mika

1 Answers

1
votes

1) Every UIView and subtype have backgroundColor by default transparent. Try to add on every view(view, button, image, stack) a white background color.

2)On your configure(with address: Address) check if you have not the same address.

3)Try to be sharp on constraint setting, the less you let Autolayout gets your layout, the less cpu is used.