如何解决自定义UITableViewCell无法正确显示
我创建了一个自定义UITableViewCell以在TableView中使用。该单元格正确显示在情节提要中,但是当我在TableView中显示它时,它似乎完全混乱了。我看过类似的问题,但是他们的问题似乎一直是网点和Xcode错误的命名。我想念什么?
UITableViewCell
class ArticleLargeTableViewCell: UITableViewCell {
public static let Identifier = "ArticleLargeTableViewCell"
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var favoriteButton: UIButton!
@IBOutlet weak var articleImage: UIImageView!
@IBOutlet weak var articleType: UIImageView!
@IBOutlet weak var articleTitle: UILabel!
@IBOutlet weak var articleDate: UILabel!
@IBOutlet weak var articleSource: UILabel!
@IBOutlet weak var articleFavicon: UIImageView!
private var shareClickListener: (Article) -> Void = { _ in }
private var favoriteClickListener: (Article) -> Void = { _ in }
private var article: Article!
override class func awakeFromNib() {
super.awakeFromNib()
}
func setData(article: Article,shareClickListener: @escaping (Article) -> Void,favoriteClickListener: @escaping (Article) -> Void,shouldShowMoreButton: Bool = true) {
self.article = article
articleImage.sd_setImage(with: article.getImageUrl())
articleImage.contentMode = UIView.ContentMode.scaleAspectFill
articleImage.clipsToBounds = true
articleTitle.text = article.title
let textColor = UIColor(named: "text")
articleTitle.textColor = textColor
articleSource.text = article.source.title
articleSource.textColor = textColor
articleDate.textColor = UIColor(named: "caption")
articleDate.text = article.date.timeAgo()
self.shareClickListener = shareClickListener
self.favoriteClickListener = favoriteClickListener
articleType.image = article.articleType().getTypeImage()
articleFavicon.sd_setImage(with: URL(string: article.faviconUrl)!)
favoriteButton.addTarget(self,action: #selector(self.onFavoriteButtonClick),for: .touchUpInside)
shareButton.addTarget(self,action: #selector(self.onShareButtonClick),for: .touchUpInside)
}
@objc func onShareButtonClick() {
shareClickListener(article)
}
@objc func onFavoriteButtonClick() {
favoriteClickListener(article)
}
}
ViewController
import Foundation
import UIKit
import Combine
import MaterialComponents.MaterialActionSheet
class ArticlesViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
@IBOutlet weak var articlesList: UITableView!
private var articles: [Article] = []
var viewModel: ArticlesViewModel!
private var useCompactView: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
articlesList.dataSource = self
articlesList.delegate = self
viewModel.$viewState.sink(receiveCompletion: { _ in},receiveValue: { viewState in
switch viewState {
case .loading:
print()
case .error:
print()
case let .data(data):
self.setData(data: data)
}
})
}
private func setData(data: ArticlesViewModel.ViewState.Data) {
self.articles = data.articles
self.title = data.title
self.useCompactView = data.useCompactView
if self.useCompactView {
articlesList.register(UINib(nibName: ArticleUiTableViewCell.Identifier,bundle: Bundle.main),forCellReuseIdentifier: ArticleUiTableViewCell.Identifier)
} else {
articlesList.register(UINib(nibName: ArticleLargeTableViewCell.Identifier,forCellReuseIdentifier: ArticleLargeTableViewCell.Identifier)
}
articlesList.reloadData()
articlesList.refreshControl?.endRefreshing()
}
func numberOfSections(in tableView: UITableView) -> Int {
1
}
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return articles.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if useCompactView {
guard let cell = articlesList.dequeueReusableCell(withIdentifier: ArticleUiTableViewCell.Identifier,for: indexPath) as? ArticleUiTableViewCell else {
fatalError("could not cast to articles cell")
}
// display other cell
} else {
guard let cell = articlesList.dequeueReusableCell(withIdentifier: ArticleLargeTableViewCell.Identifier,for: indexPath) as? ArticleLargeTableViewCell else {
fatalError("could not cast to articles cell")
}
let article = articles[indexPath.item]
cell.setData(article: article,shareClickListener: { article in
self.shareLink(description: article.title,url: article.originalUrl)
},favoriteClickListener: { article in
self.viewModel.favoriteArticle(article: article,delegate: UIApplication.shared.delegate)
})
return cell
}
}
}
我尝试返回一个明确的高度,如下所示,但是出现类似的错误。
func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
return 467
}
解决方法
更改UITableViewCell的内容视图的类可能会导致意外的行为,因为内容视图是内容的默认超级视图,而UIKit可能会对其进行一些配置。 (我在文档中找不到明确的说明)
Reference from Apple's Documentation
UITableViewCell对象的内容视图是单元格显示的内容的默认超级视图。如果您想通过简单地添加其他视图来自定义单元格,则应将其添加到内容视图中,以便在单元格进出编辑模式时适当定位。
因此,添加自定义子视图的一种解决方法是将其添加为内容视图的子视图,并使内容视图的属性保持不变。然后,您可以将所有内容包装在自定义视图中。
,修改
在看到OP的其他评论之后-他正在***更改单元格contentView
的类别-这个答案没有意义(尽管它确实会产生一个有效的单元格)。
这突出显示了在此处发布问题时包含完整详细信息的原因之一。
原始答案
要弄清楚一点,因为您没有显示所有约束。
下面是一个示例,它应该可以满足您的需求(或者至少可以使您达到所需的位置)...
布局如下:
请注意课程分配:
要对此进行测试,下面是示例代码:
class ArticleLargeTableViewCell: UITableViewCell {
public static let Identifier = "ArticleLargeTableViewCell"
@IBOutlet var title: UILabel!
@IBOutlet var source: UILabel!
}
class ArticlesViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
@IBOutlet weak var articlesList: UITableView!
let myData: [String] = [
"Source text for first row.","Longer source text which should be enough to word-wrap when running on an iPhone.","This source text\nhas embedded\nnewline characters\nto get four rows in the label."
]
override func viewDidLoad() {
super.viewDidLoad()
// articlesList.register(UINib(nibName: ArticleUiTableViewCell.Identifier,bundle: Bundle.main),forCellReuseIdentifier: ArticleUiTableViewCell.Identifier)
articlesList.register(UINib(nibName: ArticleLargeTableViewCell.Identifier,forCellReuseIdentifier: ArticleLargeTableViewCell.Identifier)
articlesList.dataSource = self
articlesList.delegate = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return myData.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ArticleLargeTableViewCell.Identifier,for: indexPath) as! ArticleLargeTableViewCell
cell.title.text = "Row \(indexPath.row)"
cell.source.text = myData[indexPath.row]
return cell
}
}
这是ArticleLargeTableViewCell.xib
文件的来源:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" 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="16087"/>
<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="402" id="9CN-96-cbN" customClass="ArticleLargeTableViewCell" customModule="TableAdd" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="414" height="402"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="9CN-96-cbN" id="hnF-dN-5dt">
<rect key="frame" x="0.0" y="0.0" width="414" height="402"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Random Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4cS-dj-yG9">
<rect key="frame" x="60" y="8" width="108" height="21"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6 minutes ago" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FaY-ve-Qel">
<rect key="frame" x="60" y="29" width="109" height="21"/>
<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="JO1-nS-Fg0">
<rect key="frame" x="8" y="8" width="44" height="44"/>
<color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="JO1-nS-Fg0" secondAttribute="height" multiplier="1:1" id="ozT-ci-zDr"/>
<constraint firstAttribute="width" constant="44" id="z0X-tH-CKE"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="tub-UY-Qc6">
<rect key="frame" x="0.0" y="129" width="414" height="207"/>
<color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="tub-UY-Qc6" secondAttribute="height" multiplier="18:9" id="Kyi-bC-PWn"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="bBl-zC-cYt">
<rect key="frame" x="386" y="8" width="20" height="20"/>
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="bBl-zC-cYt" secondAttribute="height" multiplier="1:1" id="68L-BJ-oE4"/>
<constraint firstAttribute="width" constant="20" id="qde-Gw-mBE"/>
</constraints>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aLg-Yr-ndG">
<rect key="frame" x="8" y="344" width="55" height="30"/>
<state key="normal" title="Favorite"/>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vlh-94-vuc">
<rect key="frame" x="79" y="344" width="40" height="30"/>
<state key="normal" title="Share"/>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m0R-Do-Mr3">
<rect key="frame" x="8" y="60" width="398" height="61"/>
<string key="text">Lorem ipsum dolor sit er elit lamet,consectetaur cillium adipisicing pecu,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</string>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="aLg-Yr-ndG" secondAttribute="bottom" constant="8" id="8dT-Db-15Z"/>
<constraint firstAttribute="trailing" secondItem="tub-UY-Qc6" secondAttribute="trailing" id="9MJ-uw-1Ca"/>
<constraint firstItem="tub-UY-Qc6" firstAttribute="leading" secondItem="hnF-dN-5dt" secondAttribute="leading" id="AQ3-kJ-tVu"/>
<constraint firstAttribute="trailing" secondItem="bBl-zC-cYt" secondAttribute="trailing" constant="8" id="Ble-Sl-XKb"/>
<constraint firstItem="Vlh-94-vuc" firstAttribute="leading" secondItem="aLg-Yr-ndG" secondAttribute="trailing" constant="16" id="DR1-ea-Juj"/>
<constraint firstItem="FaY-ve-Qel" firstAttribute="leading" secondItem="JO1-nS-Fg0" secondAttribute="trailing" constant="8" id="Drr-Jg-bR2"/>
<constraint firstItem="JO1-nS-Fg0" firstAttribute="leading" secondItem="hnF-dN-5dt" secondAttribute="leading" constant="8" id="OFG-JM-p5H"/>
<constraint firstItem="FaY-ve-Qel" firstAttribute="top" secondItem="4cS-dj-yG9" secondAttribute="bottom" id="RBR-GS-VdH"/>
<constraint firstItem="m0R-Do-Mr3" firstAttribute="top" secondItem="JO1-nS-Fg0" secondAttribute="bottom" constant="8" id="Ty0-OF-WPY"/>
<constraint firstItem="Vlh-94-vuc" firstAttribute="top" secondItem="tub-UY-Qc6" secondAttribute="bottom" constant="8" id="UEv-aP-CfW"/>
<constraint firstItem="bBl-zC-cYt" firstAttribute="top" secondItem="hnF-dN-5dt" secondAttribute="top" constant="8" id="WtV-1Y-RiY"/>
<constraint firstItem="JO1-nS-Fg0" firstAttribute="top" secondItem="hnF-dN-5dt" secondAttribute="top" constant="8" id="fBu-gb-Qqo"/>
<constraint firstItem="aLg-Yr-ndG" firstAttribute="top" secondItem="tub-UY-Qc6" secondAttribute="bottom" constant="8" id="kn4-84-3pp"/>
<constraint firstAttribute="trailing" secondItem="m0R-Do-Mr3" secondAttribute="trailing" constant="8" id="qQ9-nk-akg"/>
<constraint firstItem="4cS-dj-yG9" firstAttribute="leading" secondItem="JO1-nS-Fg0" secondAttribute="trailing" constant="8" id="tlM-VO-hmV"/>
<constraint firstItem="m0R-Do-Mr3" firstAttribute="leading" secondItem="hnF-dN-5dt" secondAttribute="leading" constant="8" id="ujA-dg-oXB"/>
<constraint firstItem="aLg-Yr-ndG" firstAttribute="leading" secondItem="hnF-dN-5dt" secondAttribute="leading" constant="8" id="yGd-EI-YmC"/>
<constraint firstItem="4cS-dj-yG9" firstAttribute="top" secondItem="hnF-dN-5dt" secondAttribute="top" constant="8" id="yyJ-Yv-nge"/>
<constraint firstItem="tub-UY-Qc6" firstAttribute="top" secondItem="m0R-Do-Mr3" secondAttribute="bottom" constant="8" id="zrG-g2-2ab"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="source" destination="m0R-Do-Mr3" id="SnG-VN-51c"/>
<outlet property="title" destination="4cS-dj-yG9" id="uHh-s1-WgP"/>
</connections>
<point key="canvasLocation" x="124.6376811594203" y="96.428571428571431"/>
</tableViewCell>
</objects>
</document>
在iPhone 11上的结果:
,您应该返回正确的单元格高度,UITableViewCell才能正确显示。 有两种方法:
- 固定高度:在UITableViewDelegate中实现此功能并返回值
func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
//...
}
- 如果您希望您的单元格根据其内容扩展其高度。请尝试以下两个功能
func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView,estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
//...
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。