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

Dec*_*nna 5 uitableview ios uicollectionview swift

我有一个 TableViewController,它利用其中包含 CollectionView 的单元格。这工作正常,直到我启用可访问性并将文本设置得非常大。然后应用程序陷入无限循环。

我在网上找到的涉及控制台警告的解决方案主要涉及使警告静音,因为它显然是无害的。当我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)
    }
}
Run Code Online (Sandbox Code Playgroud)

控制台输出:(此输出无限循环,直到 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.
Run Code Online (Sandbox Code Playgroud)

集合视图控制器

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明