首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当文本是一行时,TextView添加底部填充/空格

当文本是一行时,TextView添加底部填充/空格
EN

Stack Overflow用户
提问于 2022-11-01 08:55:53
回答 2查看 106关注 0票数 0

问题

我正在经历一个奇怪的行为,一个UITextView,它在一个定义了0间距的UIStackView中。UITextView用于在聊天气泡中显示消息。当消息仅为一行时,UITextView将展开并添加一个关于2.3 px的底部间距/填充。查看视图层次结构,文本本身是一个_UITextLayoutFragmentView,它位于_UITextLayoutCanvasView中。看来这个画布视图画得太大了,造成了间距。

以下图像来自显示问题所在的一行消息的视图层次结构,以及没有出现问题的两行消息:https://imgur.com/a/nvrNYZM (链接,因为我还不能在堆栈溢出上发布图像)。

我试过的

我已经将UITextView嵌入设置为:

代码语言:javascript
运行
复制
messageTextView.textContainerInset = .zero
messageTextView.textContainer.lineFragmentPadding = .zero
messageTextView.contentInset = .zero

它删除了UITextView所具有的正常填充(使用this answer/thread)。

我最初的想法是,messageTextView有一个指定的最小高度,这将导致视图在文本(一行)没有填充最小高度时展开。然而,我不知道这是否正确,或者是否有可能改变一个最小的高度。缩小字体大小会产生更大的间距。

聊天气泡使用UIStackViews自动调整其大小以适应内容。在切换到UITextView之前,我们使用了一个UILabel,它工作得很好,没有创建任何间隔。

有没有人经历过类似的问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-02 19:40:08

你显示的布局是正确的..。但有些事不太对。

我把这个作为一个快速测试-它应该非常接近你所拥有的.

单元格xib在IB中的外观:

当运行时,它的外观-5“消息”相关两次。第一组隐藏了"documentsStack和imagesStack“,第二组隐藏了它们正在显示的集合(没有子视图,但有10点高度约束):

下面是Debug视图的层次结构:

所以..。xib的来源:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="315" id="efZ-1S-bN1" customClass="RightStandardMessageCell" customModule="qtest" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="442" height="315"/>
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="efZ-1S-bN1" id="mpK-CA-Lnn">
                <rect key="frame" x="0.0" y="0.0" width="442" height="315"/>
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="2vd-KS-ll8">
                        <rect key="frame" x="106" y="8" width="328" height="299"/>
                        <color key="backgroundColor" red="0.71935945749999997" green="0.8054707646" blue="0.8795467615" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                    </imageView>
                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="7Bs-WC-QCo">
                        <rect key="frame" x="118" y="20" width="304" height="275"/>
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" translatesAutoresizingMaskIntoConstraints="NO" id="Ykv-rE-DFT">
                                <rect key="frame" x="0.0" y="0.0" width="304" height="227"/>
                                <subviews>
                                    <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Text View" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="xKc-db-bx1" userLabel="Message Text View" customClass="MyTextViewLabel" customModule="qtest" customModuleProvider="target">
                                        <rect key="frame" x="220.5" y="0.0" width="83.5" height="227"/>
                                        <color key="backgroundColor" red="0.41512373645565315" green="0.80431303791610775" blue="0.90702960527304444" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                                        <color key="textColor" systemColor="labelColor"/>
                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                        <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
                                    </textView>
                                </subviews>
                                <color key="backgroundColor" red="0.79694263352245631" green="0.91265043646398214" blue="0.50891842927836861" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                            </stackView>
                            <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jKv-au-EZL">
                                <rect key="frame" x="0.0" y="231" width="304" height="10"/>
                                <color key="backgroundColor" systemColor="systemOrangeColor"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="10" id="AoS-qw-PIV"/>
                                </constraints>
                            </stackView>
                            <stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9wb-aV-6Ah">
                                <rect key="frame" x="0.0" y="245" width="304" height="10"/>
                                <color key="backgroundColor" systemColor="systemPurpleColor"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="10" id="ZGO-O7-jpC"/>
                                </constraints>
                            </stackView>
                            <stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="wQ2-iG-u2V">
                                <rect key="frame" x="0.0" y="259" width="304" height="16"/>
                                <subviews>
                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="83z-yh-Mfn" userLabel="Timestamp">
                                        <rect key="frame" x="0.0" y="0.0" width="278" height="16"/>
                                        <constraints>
                                            <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="16" id="zeh-oM-fP6"/>
                                        </constraints>
                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                        <nil key="textColor"/>
                                        <nil key="highlightedColor"/>
                                    </label>
                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="checkmark.rectangle" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="fqI-0d-Wy4" userLabel="Checkmark Image View">
                                        <rect key="frame" x="286" y="1" width="18" height="13.5"/>
                                        <constraints>
                                            <constraint firstAttribute="width" constant="18" id="9NX-a1-Fzz"/>
                                            <constraint firstAttribute="height" constant="16" id="Pdb-F0-5qp"/>
                                        </constraints>
                                    </imageView>
                                </subviews>
                                <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                            </stackView>
                        </subviews>
                    </stackView>
                </subviews>
                <color key="backgroundColor" red="0.93024982769507736" green="0.76566540916270232" blue="0.97523039579391479" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                <constraints>
                    <constraint firstItem="2vd-KS-ll8" firstAttribute="top" secondItem="mpK-CA-Lnn" secondAttribute="top" constant="8" id="95G-hj-ZRa"/>
                    <constraint firstItem="7Bs-WC-QCo" firstAttribute="top" secondItem="2vd-KS-ll8" secondAttribute="top" constant="12" id="ARj-eW-yGu"/>
                    <constraint firstItem="2vd-KS-ll8" firstAttribute="width" relation="lessThanOrEqual" secondItem="mpK-CA-Lnn" secondAttribute="width" multiplier="0.85" id="F2v-hy-pn9"/>
                    <constraint firstItem="7Bs-WC-QCo" firstAttribute="leading" secondItem="2vd-KS-ll8" secondAttribute="leading" constant="12" id="KIV-td-SQh"/>
                    <constraint firstItem="2vd-KS-ll8" firstAttribute="trailing" secondItem="mpK-CA-Lnn" secondAttribute="trailing" constant="-8" id="P1I-QI-v0Y"/>
                    <constraint firstAttribute="bottom" secondItem="2vd-KS-ll8" secondAttribute="bottom" constant="8" id="VsS-Hf-Fv6"/>
                    <constraint firstItem="7Bs-WC-QCo" firstAttribute="trailing" secondItem="2vd-KS-ll8" secondAttribute="trailing" constant="-12" id="YAZ-d9-R8n"/>
                    <constraint firstItem="7Bs-WC-QCo" firstAttribute="bottom" secondItem="2vd-KS-ll8" secondAttribute="bottom" priority="999" constant="-12" id="ke7-OJ-E00"/>
                </constraints>
            </tableViewCellContentView>
            <connections>
                <outlet property="bubbleImageView" destination="2vd-KS-ll8" id="OIs-Qk-bNu"/>
                <outlet property="documentsStack" destination="jKv-au-EZL" id="HU0-6P-C0b"/>
                <outlet property="footerStack" destination="wQ2-iG-u2V" id="zUl-YI-Gh0"/>
                <outlet property="imagesStack" destination="9wb-aV-6Ah" id="OlB-1t-tQ5"/>
                <outlet property="messageStack" destination="Ykv-rE-DFT" id="SIz-up-iY1"/>
                <outlet property="messageTextView" destination="xKc-db-bx1" id="805-2W-d4g"/>
                <outlet property="outerStack" destination="7Bs-WC-QCo" id="bM8-CF-WYS"/>
                <outlet property="timestamp" destination="83z-yh-Mfn" id="4hp-VP-93P"/>
            </connections>
            <point key="canvasLocation" x="489.85507246376818" y="264.17410714285711"/>
        </tableViewCell>
    </objects>
    <resources>
        <image name="checkmark.rectangle" catalog="system" width="128" height="93"/>
        <systemColor name="labelColor">
            <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
        <systemColor name="systemOrangeColor">
            <color red="1" green="0.58431372549019611" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
        <systemColor name="systemPurpleColor">
            <color red="0.68627450980392157" green="0.32156862745098042" blue="0.87058823529411766" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
    </resources>
</document>

中的“文本视图充当标签”类

代码语言:javascript
运行
复制
class MyTextViewLabel: UITextView {
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() {
        isEditable = false
        isScrollEnabled = false
        showsVerticalScrollIndicator = false
        showsHorizontalScrollIndicator = false
        
        textContainerInset = .zero
        textContainer.lineFragmentPadding = .zero
        contentInset = .zero
        
        dataDetectorTypes = .all
    }
    
}

信元类

代码语言:javascript
运行
复制
class RightStandardMessageCell: UITableViewCell {
    
    @IBOutlet var bubbleImageView: UIImageView!
    @IBOutlet var messageTextView: MyTextViewLabel!
    @IBOutlet var timestamp: UILabel!

    @IBOutlet var messageStack: UIStackView!
    @IBOutlet var documentsStack: UIStackView!
    @IBOutlet var imagesStack: UIStackView!
    @IBOutlet var footerStack: UIStackView!

    @IBOutlet var outerStack: UIStackView!

    var debugColors: [UIColor] = []
    var showDebugColors: Bool = false
    var debugViews: [UIView] = []
    
    override func awakeFromNib() {
        super.awakeFromNib()
        debugViews = [
            contentView,
            bubbleImageView, messageTextView, timestamp,
            messageStack, documentsStack, imagesStack, footerStack,
            outerStack,
        ]
        debugViews.forEach { v in
            debugColors.append(v.backgroundColor ?? .clear)
        }
        // because this is the "Right Standard" call
        messageTextView.textAlignment = .right
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        bubbleImageView.layer.cornerRadius = 12.0
        bubbleImageView.layer.masksToBounds = true
        
        for (v, c) in zip(debugViews, debugColors) {
            v.backgroundColor = showDebugColors ? c : .clear
        }
        // always use the bubble image view background
        bubbleImageView.backgroundColor = UIColor(red: 0.72, green: 0.80, blue: 0.90, alpha: 1.0)
        contentView.backgroundColor = showDebugColors ? debugColors.first : .gray
    }
}

与样例控制器

代码语言:javascript
运行
复制
class MsgTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableView = UITableView()
    
    var myData: [String] = [
        "Hallo",
        "This is a longer message.",
        "Hier ist mal eine Nachricht welche sich über zwei Zeilen erstreckt.",
        "Message with\nembedded\nnewline\ncharacters.",
        "Message with data detection...\nhttps://apple.com\n770-555-1212\nme@somedomain.com"
    ]
    
    var showDebugColors: Bool = true
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemBackground
        
        // a button to toggle the cell's "debug" colors
        let btn: UIButton = {
            var cfg = UIButton.Configuration.filled()
            cfg.title = "Toggle Debug Colors"
            let b = UIButton(configuration: cfg)
            b.addTarget(self, action: #selector(toggleDebugColors(_:)), for: .touchUpInside)
            return b
        }()
        
        btn.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(btn)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(tableView)

        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([

            btn.topAnchor.constraint(equalTo: g.topAnchor, constant: 12.0),
            btn.centerXAnchor.constraint(equalTo: g.centerXAnchor),

            tableView.topAnchor.constraint(equalTo: btn.bottomAnchor, constant: 20.0),
            tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
            
        ])
        
        tableView.register(UINib(nibName: "RightStandardMessageCell", bundle: nil), forCellReuseIdentifier: "c")
        tableView.dataSource = self
        tableView.delegate = self
    }
    
    // MARK: - Table view data source
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // we'll show the same data twice
        //  - first set with documentsStack and imagesStack hidden
        //  - second set with documentsStack and imagesStack showing
        return myData.count * 2
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath) as! RightStandardMessageCell
        
        cell.timestamp.text = "Row: \(indexPath.row)"
        cell.messageTextView.text = myData[indexPath.row % myData.count]
        
        // show the documentsStack and imagesStack for the 2nd set
        cell.documentsStack.isHidden = indexPath.row < myData.count
        cell.imagesStack.isHidden = indexPath.row < myData.count

        cell.showDebugColors = self.showDebugColors
        
        return cell
    }
    
    @objc func toggleDebugColors(_ sender: Any?) -> Void {
        showDebugColors.toggle()
        tableView.reloadData()
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-11-01 09:50:16

  • 使用此SDK并应用最小高度,然后自动管理高度

https://github.com/KennethTsang/GrowingTextView

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74273529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档