微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不滚动textView的情况下使UITableViewCell的高度扩展以适合带有包装文本的UITextView的内容? 迅速5

如何解决如何在不滚动textView的情况下使UITableViewCell的高度扩展以适合带有包装文本的UITextView的内容? 迅速5

我有一个使用自定义单元格的UITableViewController。在自定义单元格内是一个UITextView和一个UIButton。我需要选定的tableView单元格适合用户输入时用户输入的多行文本。可以完美演示这一点的应用程序将是iPhone的预安装的Reminders应用程序。当前在我的应用中,tableView单元格的高度保持不变,并且textView可以在必要时进行滚动以容纳多行文本。

我尝试实施此帖子(Dynamically change cell's height while typing text,and reload the containing tableview for resize)中的解决方案,该帖子似乎提出了相同的问题,但是,该帖子已有3年历史了,即使答案仍然有效,也没有足够的示例代码让我了解如何执行答案。我没有碰碰运气,并且清除了当前的代码,避免了以前的任何尝试,因此就所需的功能而言,它目前是一个干净的状态。看到包含Swift 5中的示例代码的答案真是太神奇了。

如果有用的话,这里是自定义单元格类:

class newNoteTableViewCell: UITableViewCell {

    @IBOutlet weak var lyricsField: UITextView!
    @IBOutlet weak var recordButton: UIButton!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool,animated: Bool) {
        super.setSelected(selected,animated: animated)
    }
    
    @IBAction func recordButtonpressed(_ sender: UIButton) {
    }
}

还有我的cellForRowAt,这是除numberOfRowsInSection之外目前唯一实现的表视图委托方法

override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "lyricsCell",for: indexPath) as! newNoteTableViewCell
        
        cell.lyricsField.delegate = self
        
        cell.lyricsField.tag = indexPath.row
        
        if let safeLyrics = lyrics {
            if indexPath.row < safeLyrics.count {
                cell.lyricsField.text = safeLyrics[indexPath.row].text
            } else {
                cell.lyricsField.text = ""
            }
        }
        
        return cell
    }

解决方法

我们可以通过向您的单元格添加“回调”闭包来实现这一目的。

在编辑文本视图时,单元格类将“回调”到控制器,在这里我们可以告诉表格视图重新计算行高(以及保存编辑的文本)。

这是带有约束的简单单元格布局。确保禁用在文本视图上的滚动:

enter image description here

请注意,在设计时单元的高度无关紧要……我们的约束将允许自动布局来处理它。

结果:

enter image description here

这是示例代码:

class ExampleCell: UITableViewCell,UITextViewDelegate {
    
    @IBOutlet var recordButton: UIButton!
    @IBOutlet var lyricsField: UITextView!
    
    var callback: ((String) -> ())?
    
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        // make sure scroll is disabled
        lyricsField.isScrollEnabled = false
        // make sure delegate is set
        lyricsField.delegate = self
        // if these are set in Storyboard this func is not needed
    }
    func textViewDidChange(_ textView: UITextView) {
        let str = textView.text ?? ""
        // tell the controller
        callback?(str)
    }

}

class ExampleTableViewController: UITableViewController {

    var myData: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // start with 20 sample strings for our data
        // fill data array with 30 strings
        myData = (1...30).map { "This is row \($0)" }

        // give the second row some longer sample text
        myData[1] = "Some sample text so we see that the text view height will be automatically handled by auto-layout."
        
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }

    override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "exampleCell",for: indexPath) as! ExampleCell

        cell.lyricsField.text = myData[indexPath.row]
        
        // set the closure
        weak var tv = tableView
        cell.callback = { [weak self] str in
            guard let self = self,let tv = tv else { return }
            print("called back",str)
            // update our data with the edited string
            self.myData[indexPath.row] = str
            // we don't need to do anything else here
            // this will force the table to recalculate row heights
            tv.performBatchUpdates(nil)
        }

        return cell
    }

}

,这是情节提要的参考源:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="UxY-Y6-LYS">
    <device id="retina3_5" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Example Table View Controller-->
        <scene sceneID="HKA-46-9zH">
            <objects>
                <tableViewController id="UxY-Y6-LYS" customClass="ExampleTableViewController" customModule="Temp" customModuleProvider="target" sceneMemberID="viewController">
                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="ZaD-4v-hEm">
                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                        <prototypes>
                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="exampleCell" rowHeight="141" id="1bW-gv-rnI" customClass="ExampleCell" customModule="Temp" customModuleProvider="target">
                                <rect key="frame" x="0.0" y="28" width="320" height="141"/>
                                <autoresizingMask key="autoresizingMask"/>
                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="1bW-gv-rnI" id="H65-Gy-hPe">
                                    <rect key="frame" x="0.0" y="0.0" width="320" height="141"/>
                                    <autoresizingMask key="autoresizingMask"/>
                                    <subviews>
                                        <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5rZ-Jh-Wyd">
                                            <rect key="frame" x="96" y="11" width="128" height="30"/>
                                            <color key="backgroundColor" red="0.85215073819999998" green="0.88016217949999997" blue="0.94548028709999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                            <state key="normal" title="Record"/>
                                        </button>
                                        <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" keyboardDismissMode="onDrag" text="The Text View" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="ddd-0L-1pM">
                                            <rect key="frame" x="24" y="49" width="272" height="81"/>
                                            <color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                            <color key="textColor" systemColor="labelColor"/>
                                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                            <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
                                        </textView>
                                    </subviews>
                                    <constraints>
                                        <constraint firstItem="ddd-0L-1pM" firstAttribute="top" secondItem="5rZ-Jh-Wyd" secondAttribute="bottom" constant="8" id="MHf-Yq-xQq"/>
                                        <constraint firstAttribute="trailingMargin" secondItem="ddd-0L-1pM" secondAttribute="trailing" constant="8" id="QMH-AZ-j7k"/>
                                        <constraint firstItem="5rZ-Jh-Wyd" firstAttribute="leading" secondItem="H65-Gy-hPe" secondAttribute="leadingMargin" constant="80" id="TYR-1f-iit"/>
                                        <constraint firstAttribute="trailingMargin" secondItem="5rZ-Jh-Wyd" secondAttribute="trailing" constant="80" id="Yf1-2g-dlf"/>
                                        <constraint firstItem="5rZ-Jh-Wyd" firstAttribute="top" secondItem="H65-Gy-hPe" secondAttribute="topMargin" id="gaW-td-egM"/>
                                        <constraint firstItem="ddd-0L-1pM" firstAttribute="bottom" secondItem="H65-Gy-hPe" secondAttribute="bottomMargin" id="lKj-ML-H4Q"/>
                                        <constraint firstItem="ddd-0L-1pM" firstAttribute="leading" secondItem="H65-Gy-hPe" secondAttribute="leadingMargin" constant="8" id="uxs-rD-Pdj"/>
                                    </constraints>
                                </tableViewCellContentView>
                                <connections>
                                    <outlet property="lyricsField" destination="ddd-0L-1pM" id="9Nz-Ru-psp"/>
                                    <outlet property="recordButton" destination="5rZ-Jh-Wyd" id="qNA-Up-zLK"/>
                                </connections>
                            </tableViewCell>
                        </prototypes>
                        <connections>
                            <outlet property="dataSource" destination="UxY-Y6-LYS" id="cmh-tD-hLg"/>
                            <outlet property="delegate" destination="UxY-Y6-LYS" id="xk4-oC-WNJ"/>
                        </connections>
                    </tableView>
                </tableViewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="7mc-zX-bKw" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="330" y="127.5"/>
        </scene>
    </scenes>
    <resources>
        <systemColor name="labelColor">
            <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
    </resources>
</document>

编辑 以回复评论...。

您在单元格中的约束都是错误的...

这是您原来的xib的外观:

enter image description here

这是他们应该的外观:

enter image description here

重要:您的堆栈视图设置必须为:

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。