Вы можете сделать это, добавив свой imageView как подпредставление tableView. Затем он прокрутится вместе с клетками.
Установка его ограничений немного сложна, потому что вам нужно сделать его горизонтально относительно заднего края tableView и вертикально относительно желаемой ячейки.
Однако конечное ограничение tableView не совсем подходит для его подпредставлений, и вы не знаете местоположение ячейки, пока она не будет визуализирована.
Итак, пара вещей:
мы будем встраивать tableView в «контейнер» UIView
и использовать конечное ограничение этого представления для заднего края представления изображения.
мы создадим переменную Top Constraint и установим ее .constant
в viewDidAppear()
.
Вот пример. Это весь код (без @IBOutlets
), поэтому просто добавьте новый пустой контроллер представления и назначьте его класс TableWithSubViewViewController
:
// TableWithSubViewViewController.swift
// Created by Don Mag on 5/10/19
class SimpleOneLabelCell: UITableViewCell {
// very simple one-label tableView cell
let theLabel: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.numberOfLines = 0
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(theLabel)
NSLayoutConstraint.activate([
theLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8.0),
theLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8.0),
theLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0),
// trailing constraint set to -150, to allow room for our 120x120 imageview (with padding)
theLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -150.0),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class TableWithSubViewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let theContainerView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
let theTableView: UITableView = {
let v = UITableView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
let overlayImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
// top constraint for the image view
var overlayViewTopConstraint: NSLayoutConstraint = NSLayoutConstraint()
let reuseID = "SimpleOneLabelCell"
override func viewDidLoad() {
super.viewDidLoad()
theTableView.dataSource = self
theTableView.delegate = self
theTableView.register(SimpleOneLabelCell.self, forCellReuseIdentifier: reuseID)
// set the imageView's image
if let img = UIImage(named: "overlay") {
overlayImageView.image = img
}
// add the views
view.addSubview(theContainerView)
theContainerView.addSubview(theTableView)
theTableView.addSubview(overlayImageView)
// constrain the top of the imageView above the top of the tableView
// we'll change the constant in viewDidAppear()
overlayViewTopConstraint = overlayImageView.topAnchor.constraint(equalTo: theTableView.topAnchor, constant: -120.0)
NSLayoutConstraint.activate([
// constrain containerView to all 4 sides (safe-area)
theContainerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
theContainerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
theContainerView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
theContainerView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
// constrain tableView to all 4 sides of constainerView
theTableView.topAnchor.constraint(equalTo: theContainerView.topAnchor),
theTableView.bottomAnchor.constraint(equalTo: theContainerView.bottomAnchor),
theTableView.leadingAnchor.constraint(equalTo: theContainerView.leadingAnchor),
theTableView.trailingAnchor.constraint(equalTo: theContainerView.trailingAnchor),
// constrain the imageView using the Top Constraint we already created, plus
overlayViewTopConstraint,
// 20-pts from the right (trailing) edge of the Container View, plus
overlayImageView.trailingAnchor.constraint(equalTo: theContainerView.trailingAnchor, constant: -20.0),
// width and height at 120-pt constants
overlayImageView.widthAnchor.constraint(equalToConstant: 120.0),
overlayImageView.heightAnchor.constraint(equalToConstant: 120.0),
])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// at this point we have the table and its initial cells laid out, so we can use it for
// vertical positioning of the image view
if let c = theTableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? SimpleOneLabelCell {
// get the frame of the cell on row 1
let f = c.frame
// add half-cell-height to the origin.y
var y = f.origin.y + (f.size.height * 0.5)
// get the frame of the image view
let r = overlayImageView.frame
// subtract half-imageView-height
y -= (r.height * 0.5)
// update imageView's top constraint
overlayViewTopConstraint.constant = y
}
}
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as! SimpleOneLabelCell
cell.theLabel.text = "\(indexPath)\nLine 2\nLine 3"
return cell
}
}
Результат:
(используя это изображение я вырезал из вашего изображения):