自定义的 UITableViewCell 约束似乎被忽略了
Posted
技术标签:
【中文标题】自定义的 UITableViewCell 约束似乎被忽略了【英文标题】:Customized UITableViewCell constraints seem to be ignored 【发布时间】:2020-12-18 18:11:34 【问题描述】:我有一个带有自定义 UITableViewCell 的 UITableView(具体来说,它是一个 SwipeTableViewCell)。我有一个笔尖文件,我在其中布置了(可重复使用的)单元格。一切都按预期工作,在我的设备上看起来很好。当我完成应用程序时,我注意到我对自定义视图没有约束(其他视图中的约束工作得很好)。因此,在添加缺少的约束后,我运行了该应用程序。所有字段(4 个 UITextFields、2 个 UIImageViews)都在单元格的左上角被“挤压”。我认为我做错了什么......删除了所有这些约束......重新运行,它再次看起来不错。在重新添加约束后,同样的事情发生了。我花了几天时间试图发现我做错了什么(这是我的第一个定制单元)。我找到了一个 SO 项目:Autolayout is ignored in Custom UITableViewCell 看起来和听起来都很好,但它与我所拥有的不符,也没有解决我的问题。我也试过不使用笔尖,而是直接将文本字段和图像视图添加到原型单元格......不幸的是,结果相同。我已经阅读了很多教程,但没有一个能解决我的问题。救命!!
class EducationTableViewController: SwipeTableViewController
...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = super.tableView(tableView, cellForRowAt: indexPath) as! EducationTableCell
let education = educations[indexPath.row]
cell.configurateTheCell(education)
return cell
...
和
class EducationTableCell: SwipeTableViewCell
@IBOutlet weak var classNameLabel: UILabel!
override func prepareForReuse()
super.prepareForReuse()
classNameLabel.text = nil
// MARK: Cell Configuration
func configurateTheCell(_ education: Education)
Bundle.main.loadNibNamed("Education", owner: self, options: nil)
backgroundColor = UIColor(hexString: education.color)
let contrastingBgColor = UIColor.init(contrastingBlackOrWhiteColorOn: backgroundColor, isFlat: false)
classNameLabel.text = education.name
if (contrastingBgColor == UIColor.init(red: 0, green: 0, blue: 0, alpha: 1))
classNameLabel.textColor = K.Education.titleTextColor
else
classNameLabel.textColor = UIColor.yellow
classNameLabel.font = UIFont(name: K.UIConstants.fontNameBold, size: 35)
contentView.addSubview(classNameLabel)
...
我在 Storyboard 中为笔尖添加了约束。如果您查看上面的 SO 项目,您会看到我提到的“挤压”,但如果有帮助,我很乐意附上图片。
https://sites.google.com/view/schoolscheduler/home/junk
ios:14.3 X代码:12.3 斯威夫特 5.3.2
【问题讨论】:
您发布的一小段代码看起来有问题。如果您为您的单元格创建一个 nib/xib 文件,则没有理由调用.loadNibNamed
(除非您在那里加载另一个 nib 视图?)。另外,如果你在 IB 中设计了你的单元,为什么在运行时添加 classNameLabel
作为子视图?
嗯。我认为这是我在原型单元中看到视图时遗留下来的。让我修改并重新发布代码。
好吧,如果我省略 .loadNibNamed() 那么表中没有任何内容。我已经在 IB 中设计了单元格,但是当它不起作用时将其删除到笔尖(应用约束时视图也“挤压”)。我会贴一张我在 IB 中的照片,也许会更清楚。
嗯...有点混乱。您想要在 xib 中设计您的单元格吗?还是作为故事板原型?
好吧,我只想让它工作! ;-)。我切换回 IB,布置了单元格......在我添加第一个约束之前看起来不错,然后一切都移动到单元格的左上角(即挤压)。谷歌搜索我发现:medium.com/better-programming/…,我克隆并安装了....看起来不错。我仍在尝试看看他们做了我不做的事情。
【参考方案1】:
根据您显示的图像,您做错了一些事情。
首先,对于您使用 XIB 的尝试,您在 xib 中使用了 UIView
。应该是UITableViewCell
。
其次,原型布局...大部分看起来正确(ish)。您已经为 Class Name Label
提供了前导和尾随约束和 centerX 约束。 centerX 约束不做任何事情,因为标签已经延伸到前导值和尾随值。此外,您的 Stack View 前导约束可能应该相对于 Star Image View 的后沿,而不是单元格的前导。
看看这里显示的约束:
单元格显示为“单元格”,因为这是我给它的重用标识符,但自定义类设置为 EducationTableCell
。
输出如下:
这是产生该输出的示例代码:
import UIKit
class EducationTableCell: UITableViewCell
@IBOutlet var className: UILabel!
@IBOutlet var classLocation: UILabel!
@IBOutlet var classDays: UILabel!
@IBOutlet var classTime: UILabel!
@IBOutlet var starImageView: UIImageView!
@IBOutlet var itemImageView: UIImageView!
class EducationTableViewController: UITableViewController
override func viewDidLoad()
super.viewDidLoad()
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
return 1
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 20
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! EducationTableCell
cell.className.text = "Name \(indexPath.row)"
cell.classLocation.text = "Location \(indexPath.row)"
cell.classDays.text = "Days \(indexPath.row)"
cell.classTime.text = "Time \(indexPath.row)"
return cell
这里是 Storyboard 的源代码,因此您可以检查布局约束:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Rco-aF-G6p">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17506"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Education Table View Controller-->
<scene sceneID="0rL-fH-xZI">
<objects>
<tableViewController id="Rco-aF-G6p" customClass="EducationTableViewController" customModule="PanZoom" 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="Nk0-AL-MEx">
<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="cell" rowHeight="138" id="SUJ-72-5Po" customClass="EducationTableCell" customModule="PanZoom" 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="SUJ-72-5Po" id="G9i-wf-fpQ">
<rect key="frame" x="0.0" y="0.0" />
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="className" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mVQ-Zs-26O">
<rect key="frame" x="21" y="16" />
<color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<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" translatesAutoresizingMaskIntoConstraints="NO" id="3yA-G1-vya">
<rect key="frame" x="21" y="56.5" />
<color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="TjC-BK-Udr"/>
<constraint firstAttribute="width" secondItem="3yA-G1-vya" secondAttribute="height" multiplier="1:1" id="vWg-SJ-7vR"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cs2-jh-xoS">
<rect key="frame" x="324" y="71.5" />
<color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="ndl-Lm-Bz0"/>
<constraint firstAttribute="width" secondItem="cs2-jh-xoS" secondAttribute="height" multiplier="1:1" id="oHy-eo-dLd"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="tgj-yg-vqL">
<rect key="frame" x="81" y="46.5" />
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="classLocation" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="axi-2z-HNT">
<rect key="frame" x="0.0" y="0.0" />
<color key="backgroundColor" red="0.55634254220000001" green="0.97934550050000002" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="classDays" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UK3-x3-XGT">
<rect key="frame" x="0.0" y="26.5" />
<color key="backgroundColor" red="0.55634254220000001" green="0.97934550050000002" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="classTime" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tqR-li-CIc">
<rect key="frame" x="0.0" y="53" />
<color key="backgroundColor" red="0.55634254220000001" green="0.97934550050000002" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="bottomMargin" relation="greaterThanOrEqual" secondItem="tgj-yg-vqL" secondAttribute="bottom" constant="5" id="0xW-En-RuB"/>
<constraint firstItem="3yA-G1-vya" firstAttribute="top" secondItem="mVQ-Zs-26O" secondAttribute="bottom" constant="20" id="38Z-Q2-z0J"/>
<constraint firstItem="mVQ-Zs-26O" firstAttribute="leading" secondItem="G9i-wf-fpQ" secondAttribute="leadingMargin" constant="5" id="3J5-7X-0l3"/>
<constraint firstItem="cs2-jh-xoS" firstAttribute="leading" secondItem="tgj-yg-vqL" secondAttribute="trailing" constant="10" id="7TA-sg-Zod"/>
<constraint firstItem="mVQ-Zs-26O" firstAttribute="top" secondItem="G9i-wf-fpQ" secondAttribute="topMargin" constant="5" id="8Hh-cA-6Se"/>
<constraint firstItem="3yA-G1-vya" firstAttribute="leading" secondItem="G9i-wf-fpQ" secondAttribute="leadingMargin" constant="5" id="R99-Wc-e7A"/>
<constraint firstAttribute="trailingMargin" secondItem="cs2-jh-xoS" secondAttribute="trailing" constant="5" id="TZq-bM-V5Q"/>
<constraint firstAttribute="trailingMargin" secondItem="mVQ-Zs-26O" secondAttribute="trailing" constant="5" id="YaH-eA-zBR"/>
<constraint firstItem="cs2-jh-xoS" firstAttribute="top" secondItem="mVQ-Zs-26O" secondAttribute="bottom" constant="35" id="YcB-tX-G3j"/>
<constraint firstItem="tgj-yg-vqL" firstAttribute="top" secondItem="mVQ-Zs-26O" secondAttribute="bottom" constant="10" id="r6S-UG-b0o"/>
<constraint firstItem="tgj-yg-vqL" firstAttribute="leading" secondItem="3yA-G1-vya" secondAttribute="trailing" constant="10" id="xdc-Jv-acQ"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="classDays" destination="UK3-x3-XGT" id="3b4-tW-ATv"/>
<outlet property="classLocation" destination="axi-2z-HNT" id="59P-Dm-VIx"/>
<outlet property="className" destination="mVQ-Zs-26O" id="SaH-dm-Gxi"/>
<outlet property="classTime" destination="tqR-li-CIc" id="FNG-WI-vOC"/>
<outlet property="itemImageView" destination="cs2-jh-xoS" id="MKG-Dz-kFh"/>
<outlet property="starImageView" destination="3yA-G1-vya" id="dDq-hC-USx"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="Rco-aF-G6p" id="Ear-AM-DTS"/>
<outlet property="delegate" destination="Rco-aF-G6p" id="DsX-fk-NBi"/>
</connections>
</tableView>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ujd-EG-Zzl" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="284" y="174.96251874062969"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
【讨论】:
谢谢。将在几分钟内尝试。想说“classStarImage”并不总是出现(仅当底层记录发生更改时)因此“ClassInfo Stack View”可能无法与之绑定。我会尝试两种方式并告诉你。 你可能不相信,但你的简单代码对我不起作用。失败太容易了,但我把所有的子视图都“挤”到了左上角。我已经盯着它看了一段时间,但不明白我是怎么搞砸的。 github.com/davidhmobley/TestSchoolItems。我想了一会儿,这可能与我的新 macbook(硅)有关,所以我在我 5 岁的 macbook 上尝试了它......没有任何区别(幸运的是)。我会继续寻找。 突破!!!我刚刚在 Github 项目上注意到“推荐的”rowHeight 是 198 ......我已经将它设置为,我认为,130。当我将它重置为 200 时,它呈现得很好。现在回到我的“真实”项目。如果它有效(我认为它会),我会接受你的回答。 @DavidM - “推荐”行高无关紧要。我在您的 GitHub 项目中看到您也有不需要的行tableView.rowHeight = 150
。我还在您的项目中注意到您将单元格的 Content View
设置为与单元格相同的类 - 这几乎肯定是导致您的问题的原因。
@DavidM - 如果您只想有时显示星图视图,最好的方法可能是将starImageView
、classInfoStackView
和itemImageView
放入水平堆栈视图。然后你可以在星形图像视图上设置.isHidden
--- 除非你想要空白空间,在这种情况下保持原样(并且仍然使用.isHidden
属性来显示/隐藏它)。以上是关于自定义的 UITableViewCell 约束似乎被忽略了的主要内容,如果未能解决你的问题,请参考以下文章
具有 AccessoryType 的自定义 UITableViewCell 打破了约束