swift - 如何根据条件为单元格正确分配样式,而不会在快速滚动后出现奇怪的样式行为?
问题描述
我阅读了很多关于滚动 TableView 的内容,一般的答案是我必须使用 prepareForReuse 再次设置元素样式并重置图像。
我的问题仍然存在。如果我滚动得足够快,我在单元格中的预览图像不是一个圆圈,而是一个 5px 的圆形边框,尽管条件从未满足。
这里的魔力在哪里,我总是有想要的条件结果?postType == 0 = 照片(应该是圆形的),postType == 2 = 文本,应该有圆角。
主视图
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableViewNew.dequeueReusableCell(withIdentifier: "cellNewPosts", for: indexPath) as! MainNewTableViewCell
cell.post = posts[indexPath.row]
return cell
}
我的自定义单元格
import UIKit
import AVKit
import SDWebImage
class MainNewTableViewCell: UITableViewCell {
// Storyboard
@IBOutlet weak var viewContainer: ShadowedView! {
didSet {
viewContainer.layer.cornerRadius = 10
viewContainer.backgroundColor = .white
viewContainer.shadowColor = colorGrey
viewContainer.shadowRadius = 1
}
}
@IBOutlet weak var imageViewPreview: UIImageView! {
didSet {
imageViewPreview.backgroundColor = .white
imageViewPreview.layer.cornerRadius = imageViewPreview.frame.height / 2
}
}
@IBOutlet weak var viewContainerPreview: UIView! {
didSet {
viewContainerPreview.backgroundColor = .white
viewContainerPreview.layer.cornerRadius = viewContainerPreview.frame.height / 2
viewContainerPreview.layer.borderWidth = 2
viewContainerPreview.layer.borderColor = colorLightGrey.cgColor
}
}
@IBOutlet weak var labelPostFromCity: UILabel! {
didSet {
labelPostFromCity.layer.shadowColor = colorLightGrey.cgColor
labelPostFromCity.layer.shadowRadius = 1
labelPostFromCity.layer.shadowOpacity = 1
labelPostFromCity.layer.shadowOffset = CGSize(width: 1, height: 1)
labelPostFromCity.layer.masksToBounds = false
}
}
@IBOutlet weak var labelPostFromCountry: UILabel!
@IBOutlet weak var labelPostDate: UILabel!
@IBOutlet weak var imageTextBubble: UIImageView! {
didSet {
imageTextBubble.tintColor = colorDarkPastelBlue
}
}
@IBOutlet weak var imageHeart: UIImageView!
@IBOutlet weak var labelAmountLikes: UILabel!
@IBOutlet weak var labelAmountComments: UILabel!
// Variables
// AVPlayer Looper
var playerLooper: NSObject?
var playerLayer: AVPlayerLayer!
var queuePlayer: AVQueuePlayer?
var player: AVPlayer?
var mediaToUpload: Data?
var movieString: String?
var movieUrl: URL?
var post: PostModel? {
didSet {
guard let _postFromCity = post?.postFromCity else { return }
guard let _postFromCountry = post?.postFromCountry else { return }
guard let _postDate = post?.postDate else { return }
guard let _postMediaUrl = post?.postMediaUrl else { return }
guard let _postType = post?.postType else { return }
guard let _postText = post?.postText else { return }
setupViewCell(postFromCity: _postFromCity, postFromCountry: _postFromCountry, postDate: _postDate, postMediaUrl: _postMediaUrl, postType: _postType, postText: _postText)
}
}
func setupViewCell(postFromCity: String, postFromCountry: String, postDate: Double, postMediaUrl: String, postType: Int, postText: String) {
imageViewPreview.image = nil
labelPostFromCity.text = postFromCity
labelPostFromCountry.text = postFromCountry
let postDate = postDate
let formattedPostDate = Date(timeIntervalSince1970: postDate)
let timeAgo = formattedPostDate.timeAgo(numericDates: false)
labelPostDate.text = timeAgo
if postType == 0 {
imageViewPreview.layer.cornerRadius = imageViewPreview.frame.height / 2
viewContainerPreview.layer.cornerRadius = viewContainerPreview.frame.height / 2
let mappedUrl = URL(string: postMediaUrl)
imageViewPreview.sd_imageIndicator = SDWebImageActivityIndicator.white
imageViewPreview.sd_setImage(with: mappedUrl) {(_, _, _, _) in }
}
if postType == 1 {
}
if postType == 2 {
imageViewPreview.layer.cornerRadius = 0
viewContainerPreview.layer.cornerRadius = 10
let xxx = UIColor.clear.image(CGSize(width: 50, height: 50))
let xxxx = textToImage(drawText: postText, inImage: xxx, atPoint: CGPoint(x: 0, y: 0))
imageViewPreview.image = xxxx
}
}
// Add text to the fake preview image
func textToImage(drawText text: String, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
let textColor = UIColor.black
let textFont = UIFont(name: "Helvetica Bold", size: !
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
let textFontAttributes = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
] as [NSAttributedString.Key : Any]
image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
let rect = CGRect(origin: point, size: image.size)
text.draw(in: rect, withAttributes: textFontAttributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
override func prepareForReuse() {
imageViewPreview.layer.cornerRadius = imageViewPreview.frame.height / 2
viewContainerPreview.layer.cornerRadius = viewContainerPreview.frame.height / 2
super.prepareForReuse()
}
}
extension UIColor {
func circleImage(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
return UIGraphicsImageRenderer(size: size).image(actions: { rendererContext in
self.setFill()
rendererContext.cgContext.fillEllipse(in: CGRect(origin: .zero, size: size))
})
}
}
解决方案
希望这有助于layoutSubview()
在单元格中添加条件
func layoutSubview() {
if postType == 0 {
imageViewPreview.layer.cornerRadius = imageViewPreview.frame.height / 2
viewContainerPreview.layer.cornerRadius = viewContainerPreview.frame.height / 2
let mappedUrl = URL(string: postMediaUrl)
imageViewPreview.sd_imageIndicator = SDWebImageActivityIndicator.white
imageViewPreview.sd_setImage(with: mappedUrl) {(_, _, _, _) in }
} else if postType == 2 {
imageViewPreview.layer.cornerRadius = 0
viewContainerPreview.layer.cornerRadius = 10
let xxx = UIColor.clear.image(CGSize(width: 50, height: 50))
let xxxx = textToImage(drawText: postText, inImage: xxx, atPoint: CGPoint(x: 0, y: 0))
imageViewPreview.image = xxxx
}
}
推荐阅读
- php - HTTP ERROR 500 尝试使用 PHP 查询 .mdb Microsoft Access 数据库
- excel - 链接更新时需要暂停 VBA 脚本
- python - 如何创建字典列表的字典
- python - 根据其他参数从 JSON 中提取数据
- angular - ngModel 在 Angular 表单中的意外行为
- javascript - 如果输入为空,则添加和删除类
- php - 致命错误:内存不足(已分配 377487360)(试图分配 371200000 字节)
- javascript - 如何使用函数或变量重用模板文字?
- json - HTTP post 未完成时表单被阻止
- php - 如何与关联数组值进行比较