【问题标题】:How can I match Custom View's frame with TableViewCell frame properly?如何正确匹配自定义视图的框架与 TableViewCell 框架?
【发布时间】:2019-04-23 18:25:56
【问题描述】:

我有一个 TableView,其中包含拉伸到单元格中的图像,并且我添加了一个用于使图像变暗的视图。由于我只想在开始时绘制此视图,而不是每次在表格中滚动时都将代码添加到 TableViewCell 中的awakeFromNib

TableViewCell.swift

@IBOutlet weak var equipmentImageView: UIImageView!
let darkFilter = UIView()

override func awakeFromNib() {
    super.awakeFromNib()

    darkFilter.backgroundColor = .black
    darkFilter.layer.opacity = 0.6
    darkFilter.frame = self.equipmentImageView.frame
    equipmentImageView.addSubview(darkFilter)
}

我的问题是这个视图不会和 ImageView 有相同的宽度,所以我试图实现的效果占据了屏幕的一半。

我遵循this 解决方案,但问题是此解决方案仅在单元格通过向下和向上滚动重新创建自己之后才适用。

TableViewCell.swift

override func layoutSubviews() {
    super.layoutSubviews()
    darkFilter.backgroundColor = .black
    darkFilter.layer.opacity = 0.6
    darkFilter.frame = self.equipmentImageView.frame
    equipmentImageView.addSubview(darkFilter)

}

如何在创建单元格之前应用此解决方案并且在滚动时不会重绘?

【问题讨论】:

    标签: swift uitableview uiview


    【解决方案1】:

    您可以将单元格的.background 颜色设置为.black,然后将equipmentImageViewalpha 调低,您将获得相同的变暗效果,而无需添加新的UIView。

    编辑

    为了说明我的观点:这是我在 Playground 中使用标题为“Untitled.jpg”的图像绘制的一个非常草率且快速的示例,以证明使用黑色单元格背景褪色图像与在顶部添加褪色黑色图层相同带有图像的单元格:

    结果图片:

    代码:

    //: A UIKit based Playground for presenting user interface
    
    import UIKit
    import PlaygroundSupport
    
    
    class CustomTableViewCell: UITableViewCell {
    
        let myImageView: UIImageView = {
            let imageView = UIImageView()
            imageView.translatesAutoresizingMaskIntoConstraints = false
            imageView.contentMode = .scaleAspectFill
    
            if let sample = Bundle.main.path(forResource: "Untitled", ofType: "jpg") {
                let image = UIImage(contentsOfFile: sample)
                imageView.image = image
            }
    
            imageView.clipsToBounds = true
    
            return imageView
        }()
    
        let blackView: UIView = {
            let myView = UIView()
            myView.translatesAutoresizingMaskIntoConstraints = false
            myView.backgroundColor = .black
            return myView
        }()
    
        let title: UILabel = {
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            label.textColor = .white
            label.font = UIFont.systemFont(ofSize: 12)
            return label
        }()
    
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
    
            backgroundColor = .black
    
            let views = [myImageView,
                         blackView,
                         title]
    
            views.forEach {
                contentView.addSubview($0)
    
                NSLayoutConstraint.activate([
                    $0.heightAnchor.constraint(equalTo: contentView.heightAnchor),
                    $0.widthAnchor.constraint(equalTo: contentView.widthAnchor),
                    $0.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
                    $0.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
                    ])
            }
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func setCellViews(indexPath: IndexPath) {
            blackView.alpha = 0
    
            if indexPath.row % 2 == 0 {
                if indexPath.row % 4 == 0 {
                    blackView.alpha = 0.4
                    title.text = "blackLayer added and faded"
                } else {
                    backgroundColor = .black
                    myImageView.alpha = 0.6
                    title.text = "backView faded"
                }
            } else {
                title.text = "not faded at all"
            }
        }
    }
    
    
    private let reuseId = "cellId"
    
    class MyViewController : UIViewController {
    
        let tableView: UITableView = {
            let tableView = UITableView()
            tableView.translatesAutoresizingMaskIntoConstraints = false
            tableView.separatorStyle = .none
            return tableView
        }()
    
        let data = ["one", "two", "three", "four", "five"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            setTableView()
        }
    
        func setTableView() {
            tableView.dataSource = self
            tableView.delegate = self
            tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: reuseId)
    
            view.addSubview(tableView)
    
            NSLayoutConstraint.activate([
                tableView.heightAnchor.constraint(equalTo: view.heightAnchor),
                tableView.widthAnchor.constraint(equalTo: view.widthAnchor),
                tableView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                tableView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                ])
        }
    }
    
    extension MyViewController: UITableViewDataSource, UITableViewDelegate {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return data.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: reuseId, for: indexPath) as! CustomTableViewCell
            cell.setCellViews(indexPath: indexPath)
            return cell
        }
    
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return 50
        }
    
    }
    
    // Present the view controller in the Live View window
    PlaygroundPage.current.liveView = MyViewController()
    

    【讨论】:

    • @AhmadF 为什么不呢?观看此示例,其中设置了容器 UIView 的背景颜色,然后降低了位于容器视图顶部的 imageView 的 alpha。创建相同的效果:youtube.com/watch?v=iu9cam3XYiE&t=341s
    • 哦,明白了,抱歉。它可能是有效的,但你认为它会产生与在图像顶部添加视图完全相同的效果吗?
    • 可以,只要相对 alpha 是成比例的。
    • 我使用了 @AhmadF 的答案并得到了额外的帮助,但我很感激你的回答并尝试看看它是否有效
    • @Egrimo 我想知道为什么我的回答因为它起作用而被否决了!请不要忘记接受答案:)
    【解决方案2】:

    2 条建议:

    1) 由于您正在处理单元格的IBOutlets,因此您还可以在图像视图顶部的 IB 上添加视图,然后对其添加约束以匹配图像视图大小。

    2) 如果您打算以编程方式添加它,您可能需要根据单元格内容视图设置其约束。例如:

    darkFilter.backgroundColor = .black
    darkFilter.layer.opacity = 0.6
    
    contentView.addSubview(darkFilter)
    darkFilter.translatesAutoresizingMaskIntoConstraints = false
    darkFilter.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    darkFilter.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    darkFilter.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    darkFilter.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多