我已经在单元格内实现了带有滚动视图的表格视图。该单元格由两个视图组成,第二个视图(以绿色显示)在滑动后出现:

我现在想要实现的是,当单元格向右滑动时,单元格高度逐渐扩大。因此,当我开始向右滑动单元格并且绿色子视图在主屏幕上变得可见时,我希望单元格的高度增加,直到绿色子视图完全可见。然后当我向左滑动时,一切都恢复正常。
由于 UITableViewCell 符合滚动视图委托,我怀疑我在单元格子类中编写了一些代码 - 也许使用contentOffset.y滚动视图的scrollViewDidScroll。
这是使用自动布局和自动调整单元格大小的示例(Swift 3)。不确定您打算如何“开始”绿色视图,因此此演示将其初始化为 40 磅宽(高度包含在宽度的 50% 内)。
\n\n您只需创建一个新的 .swift 文件并将其粘贴进去,然后在 Storyboard 中添加一个 UITableViewController 并将其类分配给StretchCellTableViewController。其他一切都是在代码中创建的...不需要 IBOutlet。
//\n// StretchCellTableViewController.swift\n// SWTemp2\n//\n// Created by Don Mag on 6/22/17.\n// Copyright \xc2\xa9 2017 DonMag. All rights reserved.\n//\n\nimport UIKit\n\nclass NonStretchCell: UITableViewCell {\n\n // pretty standard one-label cell\n\n var theLabel: UILabel!\n\n override init(style: UITableViewCellStyle, reuseIdentifier: String?) {\n super.init(style: style, reuseIdentifier: reuseIdentifier)\n setupCell()\n }\n\n required init?(coder aDecoder: NSCoder) {\n super.init(coder: aDecoder)\n setupCell()\n }\n\n func setupCell() {\n\n theLabel = UILabel()\n theLabel.font = UIFont.systemFont(ofSize: 16.0, weight: UIFontWeightLight)\n theLabel.numberOfLines = 0\n theLabel.translatesAutoresizingMaskIntoConstraints = false\n\n self.addSubview(theLabel)\n\n theLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8.0).isActive = true\n theLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 6.0).isActive = true\n theLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -6.0).isActive = true\n theLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -8.0).isActive = true\n\n }\n\n}\n\nclass StretchCell: UITableViewCell {\n\n var stretchView: UIView!\n\n var widthConstraint: NSLayoutConstraint!\n\n var scaleAction : ((CGFloat)->())?\n\n override init(style: UITableViewCellStyle, reuseIdentifier: String?) {\n super.init(style: style, reuseIdentifier: reuseIdentifier)\n setupCell()\n }\n\n required init?(coder aDecoder: NSCoder) {\n super.init(coder: aDecoder)\n setupCell()\n }\n\n func setBarWidth(_ w: CGFloat) -> Void {\n widthConstraint.constant = w\n }\n\n func setupCell() {\n\n // instantiate the view\n stretchView = UIView()\n stretchView.translatesAutoresizingMaskIntoConstraints = false\n stretchView.backgroundColor = .green\n\n // add it to self (the cell)\n self.addSubview(stretchView)\n\n // "pin" it to top, bottom and left\n stretchView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0.0).isActive = true\n stretchView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0.0).isActive = true\n stretchView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0.0).isActive = true\n\n // set height constraint to be 50% of the width\n stretchView.heightAnchor.constraint(equalTo: stretchView.widthAnchor, multiplier: 0.5).isActive = true\n\n // instantiate the width constraint\n widthConstraint = NSLayoutConstraint(item: stretchView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 40)\n\n // needs priority of 999 so auto-layout doesn\'t complain\n widthConstraint.priority = 999\n\n // activate the width constraint\n NSLayoutConstraint.activate([widthConstraint])\n\n // create a UIPanGestureRecognizer and add it to the stretch view\n let panGesture = UIPanGestureRecognizer(target: self, action: #selector(didPan(sender:)))\n\n stretchView.addGestureRecognizer(panGesture)\n\n }\n\n func didPan(sender: UIPanGestureRecognizer) {\n\n let loc = sender.location(in: self)\n\n if sender.state == .began {\n\n // if you want to do something on drag start...\n //print("Gesture began")\n\n } else if sender.state == .changed {\n\n //print("Gesture is changing", loc)\n\n // update the width of the stretch view (but keep it at least 20-pts wide, so it doesn\'t disappear)\n // height is set to 1:1 so it updates automatically\n widthConstraint.constant = max(loc.x, 20)\n\n // call back to the view controller\n scaleAction?(widthConstraint.constant)\n\n } else if sender.state == .ended {\n\n // if you want to do something on drag end...\n //print("Gesture ended")\n\n }\n\n }\n\n}\n\n\nclass StretchCellTableViewController: UITableViewController {\n\n // array to track the bar widths, assuming we have more than one row with a bar\n // only a few rows will have the "stretch bar" - but for this example we\'ll just track a barWidth for *every* row\n var barWidths = [CGFloat]()\n\n override func viewDidLoad() {\n super.viewDidLoad()\n\n tableView.rowHeight = UITableViewAutomaticDimension\n tableView.estimatedRowHeight = 80\n\n tableView.register(StretchCell.self, forCellReuseIdentifier: "StretchCell")\n tableView.register(NonStretchCell.self, forCellReuseIdentifier: "NonStretchCell")\n\n // init array for barWidths... initial value: 40, 30 slots\n barWidths = Array(repeating: 40, count: 30)\n }\n\n override func numberOfSections(in tableView: UITableView) -> Int {\n return 1\n }\n\n override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n return barWidths.count\n }\n\n override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n\n // just make every 5th row a "Stretch" cell (starting at #3)\n if indexPath.row % 5 == 3 {\n let cell = tableView.dequeueReusableCell(withIdentifier: "StretchCell", for: indexPath) as! StretchCell\n cell.selectionStyle = .none\n\n // cells are reused, so set the bar width to our saved value\n cell.setBarWidth(barWidths[indexPath.row])\n\n // "call-back" function\n cell.scaleAction = {\n (newWidth) in\n // update the bar width in our tracking array\n self.barWidths[indexPath.row] = newWidth\n\n // disable Animations, because we\'re changing the size repeatedly\n UIView.setAnimationsEnabled(false)\n\n // wrap begin/end updates() to force row-height re-calc\n self.tableView.beginUpdates()\n self.tableView.endUpdates()\n\n // re-enable Animations\n UIView.setAnimationsEnabled(true)\n }\n\n cell.preservesSuperviewLayoutMargins = false\n cell.separatorInset = UIEdgeInsets.zero\n cell.layoutMargins = UIEdgeInsets.zero\n\n return cell\n }\n\n let cell = tableView.dequeueReusableCell(withIdentifier: "NonStretchCell", for: indexPath) as! NonStretchCell\n\n // just for demonstration\'s sake\n\n if indexPath.row % 7 == 5 {\n cell.theLabel.text = "Row: \\(indexPath.row) - This is just to show the text wrapping onto multiple lines. Pretty standard for auto-sizing UITableView cells."\n } else {\n cell.theLabel.text = "Row: \\(indexPath.row)"\n }\n\n cell.preservesSuperviewLayoutMargins = false\n cell.separatorInset = UIEdgeInsets.zero\n cell.layoutMargins = UIEdgeInsets.zero\n\n return cell\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n结果是:
\n\n\n