为啥忽略拥抱优先级?
Posted
技术标签:
【中文标题】为啥忽略拥抱优先级?【英文标题】:Why Hugging priority is ignored?为什么忽略拥抱优先级? 【发布时间】:2021-10-19 05:22:24 【问题描述】:我制作了一个文本气泡,它有 2 个带有超级视图的动态水平约束:左侧优先级为 1000,右侧优先级为 100。如果气泡是由用户创建的,left 约束将具有 100 优先级,right 将具有 1000 优先级。
在 Bubble 内部有带有标签的 StackView。堆栈视图被限制为与气泡相同的大小。 标签的拥抱和压缩优先级都高于100和低于1000(但上标签优先于下标签)。
想法很简单,优先级为 100 的约束将被打破,气泡将尽可能大,以显示整个文本。
但是它不起作用。气泡比应有的大得多。似乎自动布局忽略了拥抱优先级。
这里是气泡的所有约束的描述,带有文本“Hhbhj”:
<NSLayoutConstraint:0x283341630 V:|-(10)-[UIStackView:0x113310d90] (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283341810 H:[UIView:0x113310c20]-(>=16)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x2833414a0 UILabel:0x113311360.height >= 14 priority:999 (active)>
<NSLayoutConstraint:0x2833416d0 V:|-(6)-[UIView:0x113310c20] (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341540 H:|-(10)-[UIStackView:0x113310d90] (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x2833415e0 V:[UIStackView:0x113310d90]-(10)-| (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283340be0 UIImageView:0x113310f20.width == 0 priority:1 (active)>
<NSLayoutConstraint:0x283341680 H:[UIView:0x113310c20]-(16)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341360 UILabel:0x1133110f0.height >= 24 priority:999 (active)>
<NSLayoutConstraint:0x2833417c0 H:|-(16@100)-[UIView:0x113310c20] priority:100 (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341770 H:|-(>=16)-[UIView:0x113310c20] (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283340c80 UIImageView:0x113310f20.height == 183 priority:999 (active)>
<NSLayoutConstraint:0x283341590 H:[UIStackView:0x113310d90]-(10)-| (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283341720 V:[UIView:0x113310c20]-(6)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
P.S 您还可以在气泡中看到 imageView。如果气泡中没有图像,请不要担心 imageView 将被隐藏并停用约束。 P.S.S 两个垂直大于约束,只要确保气泡不会变得比他们需要的大。
【问题讨论】:
你能显示激活约束的完整列表吗?此外,检查日志以查看是否有任何冲突的约束随后被破坏。 没有冲突。我用文本“Hhbhj”添加了气泡的约束 【参考方案1】:这是解决此问题的一种方法...
对于您的标签,请给出顶部(消息)标签:
Content Hugging Priority
Horizontal: 750
Vertical: 1000
Content Compression Resistance Priority
Horizontal: 1000
Vertical: 750
并给出底部(时间)标签:
Content Hugging Priority
Horizontal: 251
Vertical: 1000
Content Compression Resistance Priority
Horizontal: 1000
Vertical: 750
这里有两个示例...顶部的示例将“气泡视图”限制为单元格的Content View
边距。底部的将“气泡视图”的 width 限制为单元格宽度的 80%。
像这样设置你的约束 - 全部使用Priority: 1000
:
为前导和尾随约束定义 @IBOutlet
vars:
@IBOutlet var sentConstraint: NSLayoutConstraint!
@IBOutlet var receivedConstraint: NSLayoutConstraint!
将sentConstraint
连接到Bubble View.trailing = trailingMargin
约束,并将receivedConstraint
连接到Bubble View.leading = leadingMargin
约束。
它现在看起来像这样:
为单元格设置数据时,激活/停用相应的约束,例如:
// activate / deactivate Trailing / Leading constraints
// based on sent or received
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
>=
Leading 和 Trailing 约束将阻止气泡视图延伸到内容视图框架之外。
它的外观如下:
在消息传递应用程序中,在侧面留下一些“填充”是很常见的。通过将气泡视图的宽度限制为 80%,它可能看起来像这样:
这是我用来生成此布局的代码:
enum MessageType
case sent, received
struct MessageStruct
var imageName: String = ""
var message: String = ""
var time: String = ""
var type: MessageType = .sent
class BubbleCell: UITableViewCell
@IBOutlet var bubbleView: UIView!
@IBOutlet var myImageView: UIImageView!
@IBOutlet var messageLabel: UILabel!
@IBOutlet var timeLabel: UILabel!
@IBOutlet var sentConstraint: NSLayoutConstraint!
@IBOutlet var receivedConstraint: NSLayoutConstraint!
func fillData(_ msg: MessageStruct) -> Void
// I don't know how you're getting / setting your possible image,
// so I'll just set it to hidden for now
myImageView.isHidden = true
// set message label text
messageLabel.text = msg.message
// set time label text, append either sent or rec'd
// and set alignment
timeLabel.text = msg.time + (msg.type == .sent ? " - sent" : " - rec'd")
timeLabel.textAlignment = msg.type == .sent ? .right : .left
// set colors based on sent or received
bubbleView.backgroundColor = msg.type == .sent ? .systemGreen : .white
messageLabel.textColor = msg.type == .sent ? .white : .black
timeLabel.textColor = msg.type == .sent ? .white : .black
// activate / deactivate Trailing / Leading constraints
// based on sent or received
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
// set corner radii based on sent or received
bubbleView.layer.cornerRadius = 16
bubbleView.layer.maskedCorners = msg.type == .sent
? [.layerMaxXMinYCorner, .layerMinXMinYCorner, .layerMinXMaxYCorner]
: [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMinYCorner]
class MessageTableViewController: UITableViewController
var myData: [MessageStruct] = []
override func viewDidLoad()
super.viewDidLoad()
var msg: MessageStruct!
msg = MessageStruct(imageName: "",
message: "Short message.",
time: "09:15",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Short message.",
time: "09:15",
type: .received)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This is a longer message.",
time: "09:20",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This is a longer message.",
time: "09:20",
type: .received)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This message should be long enough that it needs to wrap in the cell.",
time: "09:25",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another Short message.",
time: "09:30",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another message, long enough that it will need to wrap in the cell.",
time: "09:35",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another message, long enough that it will need to wrap in the cell.",
time: "09:35",
type: .received)
myData.append(msg)
tableView.separatorStyle = .none
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return myData.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
// use "bubbleCell" identifier for margin-width limit
// use "bubble80Cell" identifier for 80% width limit
let c = tableView.dequeueReusableCell(withIdentifier: "bubbleCell", for: indexPath) as! BubbleCell
let d = myData[indexPath.row]
c.fillData(d)
return c
这里是 Storyboard 源代码,您可以查看它:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="ios.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="t48-nh-14V">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Message Table View Controller-->
<scene sceneID="mMr-vR-h6X">
<objects>
<tableViewController id="t48-nh-14V" customClass="MessageTableViewController" customModule="QuickTest" 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="BrW-mC-6e6">
<rect key="frame" x="0.0" y="0.0" />
<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="bubbleCell" rowHeight="260" id="Oi2-T7-oyW" customClass="BubbleCell" customModule="QuickTest" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" />
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Oi2-T7-oyW" id="gQY-hx-B2I">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h2Z-Bt-MGu">
<rect key="frame" x="16" y="11" />
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="wrN-dr-6PW">
<rect key="frame" x="8" y="12" />
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Aio-Ve-8b1">
<rect key="frame" x="0.0" y="0.0" />
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="83w-nH-MFV">
<rect key="frame" x="0.0" y="171.5" />
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="13:50 - sent" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3MO-It-xQw">
<rect key="frame" x="0.0" y="198" />
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemGreenColor"/>
<constraints>
<constraint firstItem="wrN-dr-6PW" firstAttribute="top" secondItem="h2Z-Bt-MGu" secondAttribute="top" constant="12" id="61F-T7-VXd"/>
<constraint firstAttribute="trailing" secondItem="wrN-dr-6PW" secondAttribute="trailing" constant="8" id="Aso-zu-ZPc"/>
<constraint firstItem="wrN-dr-6PW" firstAttribute="leading" secondItem="h2Z-Bt-MGu" secondAttribute="leading" constant="8" id="bsG-sY-260"/>
<constraint firstAttribute="bottom" secondItem="wrN-dr-6PW" secondAttribute="bottom" constant="12" id="oAO-Jt-UX3"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.897361517" green="0.8974906802" blue="0.89733326440000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailingMargin" relation="greaterThanOrEqual" secondItem="h2Z-Bt-MGu" secondAttribute="trailing" id="6hf-N2-14b"/>
<constraint firstAttribute="bottomMargin" secondItem="h2Z-Bt-MGu" secondAttribute="bottom" id="FxF-PE-6iW"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="gQY-hx-B2I" secondAttribute="leadingMargin" id="Wsa-eO-InO"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="top" secondItem="gQY-hx-B2I" secondAttribute="topMargin" id="ZYU-hS-2Pl"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="trailing" secondItem="gQY-hx-B2I" secondAttribute="trailingMargin" id="edX-9l-Ye2"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="leading" secondItem="gQY-hx-B2I" secondAttribute="leadingMargin" id="s0J-rx-Rzx"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="bubbleView" destination="h2Z-Bt-MGu" id="uJ0-t9-ZQ9"/>
<outlet property="messageLabel" destination="83w-nH-MFV" id="pEd-Gg-49x"/>
<outlet property="myImageView" destination="Aio-Ve-8b1" id="qJQ-G9-Qc6"/>
<outlet property="receivedConstraint" destination="s0J-rx-Rzx" id="fCI-9h-2V1"/>
<outlet property="sentConstraint" destination="edX-9l-Ye2" id="KKm-FT-Zcq"/>
<outlet property="timeLabel" destination="3MO-It-xQw" id="bxt-vZ-c2v"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="bubble80Cell" rowHeight="260" id="DAc-Zm-a8s" customClass="BubbleCell" customModule="QuickTest" customModuleProvider="target">
<rect key="frame" x="0.0" y="288" />
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="DAc-Zm-a8s" id="te5-Rn-aLa">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lFi-s6-a3X">
<rect key="frame" x="16" y="11" />
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="HX0-dn-sRz">
<rect key="frame" x="8" y="12" />
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Xsw-i1-9mU">
<rect key="frame" x="0.0" y="0.0" />
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Zs-Af-RNQ">
<rect key="frame" x="0.0" y="171.5" />
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="13:50 - sent" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7nV-rU-i4W">
<rect key="frame" x="0.0" y="198" />
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemGreenColor"/>
<constraints>
<constraint firstItem="HX0-dn-sRz" firstAttribute="leading" secondItem="lFi-s6-a3X" secondAttribute="leading" constant="8" id="6Kk-f4-tiB"/>
<constraint firstItem="HX0-dn-sRz" firstAttribute="top" secondItem="lFi-s6-a3X" secondAttribute="top" constant="12" id="7H5-6V-Ag0"/>
<constraint firstAttribute="trailing" secondItem="HX0-dn-sRz" secondAttribute="trailing" constant="8" id="Czf-wx-QBQ"/>
<constraint firstAttribute="bottom" secondItem="HX0-dn-sRz" secondAttribute="bottom" constant="12" id="edZ-aP-M1N"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.897361517" green="0.8974906802" blue="0.89733326440000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="lFi-s6-a3X" firstAttribute="trailing" secondItem="te5-Rn-aLa" secondAttribute="trailingMargin" id="Ua5-F4-YR5"/>
<constraint firstAttribute="bottomMargin" secondItem="lFi-s6-a3X" secondAttribute="bottom" id="WKr-87-LJK"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="leading" secondItem="te5-Rn-aLa" secondAttribute="leadingMargin" id="h4U-ie-xYq"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="width" relation="lessThanOrEqual" secondItem="te5-Rn-aLa" secondAttribute="width" multiplier="0.8" id="sKr-Xc-5bn"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="top" secondItem="te5-Rn-aLa" secondAttribute="topMargin" id="ueL-NI-qoX"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="bubbleView" destination="lFi-s6-a3X" id="5qj-C0-Uf3"/>
<outlet property="messageLabel" destination="6Zs-Af-RNQ" id="YTU-M9-s7P"/>
<outlet property="myImageView" destination="Xsw-i1-9mU" id="Unr-HS-Iv1"/>
<outlet property="receivedConstraint" destination="h4U-ie-xYq" id="tCy-cc-uHa"/>
<outlet property="sentConstraint" destination="Ua5-F4-YR5" id="Kgg-gY-JCv"/>
<outlet property="timeLabel" destination="7nV-rU-i4W" id="GUX-T1-4Nc"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="t48-nh-14V" id="3oa-OS-rO8"/>
<outlet property="delegate" destination="t48-nh-14V" id="7Ua-sV-mwS"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="fpm-tv-1pb"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2On-8d-2Kp" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1447.2" y="-749.7751124437782"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
编辑
值得注意——如果我们替换fillData()
中的这两行:
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
这些:
sentConstraint.priority = msg.type == .sent ? .defaultHigh : .defaultLow
receivedConstraint.priority = msg.type == .received ? .defaultHigh : .defaultLow
我们将实现相同的目标。
没有看到您的实际布局(很难解读您发布的“所有约束的描述”),也没有看到您正在使用的代码,很难说出为什么这不适合您。
【讨论】:
它有效。谢谢。你知道为什么你应该停用约束而不是降低它的优先级。这两种方法都不应该有效吗? @ShynggysSaparbek - 请参阅答案末尾的 编辑。以上是关于为啥忽略拥抱优先级?的主要内容,如果未能解决你的问题,请参考以下文章