当启用大/可访问文本时,调用tableView.scrollToRow会触发无限循环

时间:2018-05-01 15:08:12

标签: ios swift uitableview uicollectionview

我有一个TableViewController,它利用其中包含CollectionView的Cell。这工作正常,直到我启用辅助功能并将文本设置得非常大。该应用程序然后陷入无限循环。

我在网上找到的解决方案涉及控制台中的警告,主要涉及使警告静音,因为它显然是无害的。当我为UICollectionViewFlowLayoutBreakForInvalidSizes设置断点时,我将带到嵌入CollectionViews的单元格的TableViewController。当我尝试在collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath)中修改CollectionView的大小时,永远不会调用该函数。

为什么会发生这种崩溃,我该怎么做才能阻止它?

崩溃功能

    /**
 This function triggers the refreshing of the table view's last row when the data source was updated.
 We assume only the last row ever changes.

 It then prompts the table view to scroll to its last cell.
 **/
fileprivate func updateLastRow() {
    DispatchQueue.main.async {
        let lastIndexPath = IndexPath(row: self.currentSteps.count - 1, section: 0)

        self.tableView.beginUpdates()
        self.tableView.insertRows(at: [lastIndexPath], with: .none)
        self.tableView.endUpdates()

        self.tableView.layoutIfNeeded()
        self.adjustInsets()
        //We never leave the below function.
        self.tableView.scrollToRow(at: lastIndexPath,
                                   at: UITableViewScrollPosition.bottom,
                                   animated: true)
    }
}

控制台输出:(此输出无限循环,直到XCode崩溃)

2018-05-01 11:34:43.476977+0200 TestApp[6751:151048] Please check the values returned by the delegate.
2018-05-01 11:34:43.477183+0200 TestApp[6751:151048] The relevant UICollectionViewFlowLayout instance is <TestApp.OnboardingChatActionCollectionViewController: 0x7f9ee023ff30>, and it is attached to <UICollectionView: 0x7f9ede16ce00; frame = (28 1442.5; 291 68); clipsToBounds = YES; alpha = 0; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x6000002582d0>; layer = <CALayer: 0x600000432a00>; contentOffset: {0, 0}; contentSize: {291, 58}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <TestApp.OnboardingChatActionCollectionViewController: 0x7f9ee023ff30>.
2018-05-01 11:34:43.477294+0200 TestApp[6751:151048] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
2018-05-01 11:34:43.477500+0200 TestApp[6751:151048] The behavior of the UICollectionViewFlowLayout is not defined because:
2018-05-01 11:34:43.477665+0200 TestApp[6751:151048] the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.

CollectionViewController

import UIKit

private let reuseIdentifier = "ChatActionButtonCell"

/// ViewController for managing chat action buttons
class OnboardingChatActionCollectionViewController: UICollectionViewFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {

    var onboardingCellDelegate: BaseOnboardingTableViewCell?


    /// This will link a UICollectionView to this controller
    func attach(toCollection collection: UICollectionView) {
        collection.delegate = self
        collection.dataSource = self
        collection.collectionViewLayout = self

        collection.contentInset.left = 0
        collection.contentInset.right = 0

        collection.backgroundColor = .clear

        self.estimatedItemSize = CGSize(width: 50, height: 29)


        collection.register(UINib(nibName: "ChatActionButton", bundle: nil), forCellWithReuseIdentifier: "ChatActionButtonCell")
    }


    /// Renders buttons inactive and greys them out (based on user selection) after an action was tapped
    fileprivate func greyOutButtons(selectedCell: OnboardingChatActionCollectionViewCell) {
        DispatchQueue.main.async {

            let cells = self.collectionView?.visibleCells as! [OnboardingChatActionCollectionViewCell]

            for cell in cells {
                if cell == selectedCell {
                    cell.background.backgroundColor = .charcoalGrey
                } else {
                    cell.background.backgroundColor = .aqua10
                    cell.actionButton.setTitleColor(.gunmetal, for: .normal)
                }

                cell.actionButton.isEnabled = false
            }
        }
    }


    /// Wrapping buttons on a new row if they're too large
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let attributes = super.layoutAttributesForElements(in: rect)

        var leftMargin = sectionInset.left
        var maxY: CGFloat = -1.0
        attributes?.forEach { layoutAttribute in
            if layoutAttribute.frame.origin.y >= maxY {
                leftMargin = sectionInset.left
            }

            layoutAttribute.frame.origin.x = leftMargin

            leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
            maxY = max(layoutAttribute.frame.maxY , maxY)
        }

        return attributes
    }


    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return onboardingCellDelegate?.onboardingStep.chatActions?.count ?? 0
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let chatActionCell = self.collectionView?.dequeueReusableCell(withReuseIdentifier: "ChatActionButtonCell", for: indexPath) as! OnboardingChatActionCollectionViewCell

        chatActionCell.chatAction = onboardingCellDelegate?.onboardingStep.chatActions?[indexPath.row]

        chatActionCell.background.layer.cornerRadius = chatActionCell.background.frame.height / 2
        chatActionCell.sizeToFit()

        chatActionCell.collectionControllerDelegate = self

        return chatActionCell
    }
}

如何在没有放大文字的情况下显示TableView (启用较大文本时不会加载)

enter image description here

0 个答案:

没有答案