自定义UITableViewCell无法正确显示

如何解决自定义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
        }
    }
 
}

自动版式

输出

enter image description here

我尝试返回一个明确的高度,如下所示,但是出现类似的错误。

func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 467
}

解决方法

更改UITableViewCell的内容视图的类可能会导致意外的行为,因为内容视图是内容的默认超级视图,而UIKit可能会对其进行一些配置。 (我在文档中找不到明确的说明)

Reference from Apple's Documentation

UITableViewCell对象的内容视图是单元格显示的内容的默认超级视图。如果您想通过简单地添加其他视图来自定义单元格,则应将其添加到内容视图中,以便在单元格进出编辑模式时适当定位。

因此,添加自定义子视图的一种解决方法是将其添加为内容视图的子视图,并使内容视图的属性保持不变。然后,您可以将所有内容包装在自定义视图中。

Avoid changing the class of content view

,

修改

在看到OP的其他评论之后-他正在***更改单元格contentView的类别-这个答案没有意义(尽管它确实会产生一个有效的单元格)。

这突出显示了在此处发布问题时包含完整详细信息的原因之一。


原始答案

要弄清楚一点,因为您没有显示所有约束。

下面是一个示例,它应该可以满足您的需求(或者至少可以使您达到所需的位置)...

布局如下:

enter image description here

请注意课程分配:

enter image description here

enter image description here

要对此进行测试,下面是示例代码:

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上的结果:

enter image description here

enter image description here

,

您应该返回正确的单元格高度,UITableViewCell才能正确显示。 有两种方法:

  1. 固定高度:在UITableViewDelegate中实现此功能并返回值
func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
//...
}
  1. 如果您希望您的单元格根据其内容扩展其高度。请尝试以下两个功能
func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView,estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
//...
}

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

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-