- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个水平的 UICollectionView
固定到 UITableViewCell
的所有边缘。 Collection View 中的项目是动态调整大小的,我想让 TableView 的高度等于最高的 Collection View 单元格的高度。
View 的结构如下:
UITableView
UITableViewCell
UICollectionView
UICollectionViewCell
UICollectionViewCell
UICollectionViewCell
class TableViewCell: UITableViewCell {
private lazy var collectionView: UICollectionView = {
let collectionView = UICollectionView(frame: self.frame, collectionViewLayout: layout)
return collectionView
}()
var layout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = CGSize(width: 350, height: 20)
layout.scrollDirection = .horizontal
return layout
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let nib = UINib(nibName: String(describing: CollectionViewCell.self), bundle: nil)
collectionView.register(nib, forCellWithReuseIdentifier: CollectionViewCellModel.identifier)
addSubview(collectionView)
// (using SnapKit)
collectionView.snp.makeConstraints { (make) in
make.leading.equalToSuperview()
make.trailing.equalToSuperview()
make.top.equalToSuperview()
make.bottom.equalToSuperview()
}
}
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
collectionView.layoutIfNeeded()
collectionView.frame = CGRect(x: 0, y: 0, width: targetSize.width , height: 1)
return layout.collectionViewContentSize
}
override func layoutSubviews() {
super.layoutSubviews()
let spacing: CGFloat = 50
layout.sectionInset = UIEdgeInsets(top: 0, left: spacing, bottom: 0, right: spacing)
layout.minimumLineSpacing = spacing
}
}
class OptionsCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
contentView.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
return contentView.systemLayoutSizeFitting(CGSize(width: targetSize.width, height: 1))
}
}
class CollectionViewFlowLayout: UICollectionViewFlowLayout {
private var contentHeight: CGFloat = 500
private var contentWidth: CGFloat = 200
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
if let attrs = super.layoutAttributesForElements(in: rect) {
// perform some logic
contentHeight = /* something */
contentWidth = /* something */
return attrs
}
return nil
}
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
}
在我的 UIViewController
中,我有 tableView.estimatedRowHeight = 500
和 tableView.rowHeight = UITableView.automaticDimension
。
我试图使 systemLayoutSizeFitting
中的表格 View 单元格的大小等于 collectionViewContentSize
,但它在布局有机会设置 之前被调用collectionViewContentSize
到正确的值。以下是调用这些方法的顺序:
cellForRowAt
CollectionViewFlowLayout collectionViewContentSize: (200.0, 500.0) << incorrect/original value
**OptionsTableViewCell systemLayoutSizeFitting (200.0, 500.0) << incorrect/original value**
CollectionViewFlowLayout collectionViewContentSize: (200.0, 500.0) << incorrect/original value
willDisplay cell
CollectionViewFlowLayout collectionViewContentSize: (200.0, 500.0) << incorrect/original value
TableViewCell layoutSubviews() collectionViewContentSize.height: 500.0 << incorrect/original value
CollectionViewFlowLayout collectionViewContentSize: (200.0, 500.0) << incorrect/original value
CollectionViewFlowLayout layoutAttributesForElements
CollectionViewFlowLayout collectionViewContentSize: (450.0, 20.0)
CollectionViewFlowLayout layoutAttributesForElements
CollectionViewFlowLayout collectionViewContentSize: (450.0, 20.0)
CollectionViewCell systemLayoutSizeFitting
CollectionViewCell systemLayoutSizeFitting
CollectionViewCell systemLayoutSizeFitting
CollectionViewFlowLayout collectionViewContentSize: (450.0, 20.0)
CollectionViewFlowLayout layoutAttributesForElements
CollectionViewFlowLayout collectionViewContentSize: (450.0, 301.0) << correct size
CollectionViewFlowLayout collectionViewContentSize: (450.0, 301.0) << correct size
TableViewCell layoutSubviews() collectionViewContentSize.height: 301.0 << correct height
CollectionViewFlowLayout layoutAttributesForElements
CollectionViewFlowLayout collectionViewContentSize: (450.0, 301.0) << correct size
TableViewCell layoutSubviews() collectionViewContentSize.height: 301.0 << correct height
如何使我的表格 View 单元格的高度等于我的 Collection View 的最高项目,由布局的 collectionViewContentSize
表示?
最佳答案
有一些步骤可以实现这一点:
UICollectionViewCell
UICollectionView
UITableViewCell
bounds
更改的高阶 View UICollectionViewCell
这里有两个选择:- 将自动布局与自调整 UI 元素(如 UIImageView
或 UILabel
等)结合使用- 计算并提供您自己的尺寸
-将自动布局与自调整 UI 元素结合使用:
如果您将 estimatedItemsSize
设置为 automatic
并使用自调整 UI 元素正确布局单元格 subview ,它将在运行时自动调整大小。 但 请注意由于复杂的布局而导致的昂贵的布局时间和滞后。特别是在旧设备上。
-计算并提供您自己的尺寸:
您可以设置单元格大小的最佳位置之一是 intrinsicContentSize
。尽管还有其他地方可以执行此操作(例如在 flowLayout 类等中),但这是您可以保证单元格不会与其他自调整 UI 元素冲突的地方:
override open var intrinsicContentSize: CGSize { return /*CGSize you prefered*/ }
UICollectionView
任何 UIScrollView
子类都可以根据它的 contentSize
自调整大小。由于 collectionView 和 tableView 的内容大小不断变化,您应该通知 layouter
(在任何地方都正式称为 layouter):
protocol CollectionViewSelfSizingDelegate: class {
func collectionView(_ collectionView: UICollectionView, didChageContentSizeFrom oldSize: CGSize, to newSize: CGSize)
}
class SelfSizingCollectionView: UICollectionView {
weak var selfSizingDelegate: CollectionViewSelfSizingDelegate?
override open var intrinsicContentSize: CGSize {
return contentSize
}
override func awakeFromNib() {
super.awakeFromNib()
if let floawLayout = collectionViewLayout as? UICollectionViewFlowLayout {
floawLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
} else {
assertionFailure("Collection view layout is not flow layout. SelfSizing may not work")
}
}
override open var contentSize: CGSize {
didSet {
guard bounds.size.height != contentSize.height else { return }
frame.size.height = contentSize.height
invalidateIntrinsicContentSize()
selfSizingDelegate?.collectionView(self, didChageContentSizeFrom: oldValue, to: contentSize)
}
}
}
因此,在重写 intrinsicContentSize
之后,我们会观察 contentSize 的变化,并通知需要了解这一点的 selfSizingDelegate
。
UITableViewCell
这个单元格可以通过在它们的 tableView
中实现来自动调整大小:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
我们将在这个单元格中放置一个 selfSizingCollectionView
并实现它:
class SelfSizingTableViewCell: UITableViewCell {
@IBOutlet weak var collectionView: SelfSizingCollectionView!
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
return collectionView.frame.size
}
override func awakeFromNib() {
...
collectionView.selfSizingDelegate = self
}
}
所以我们符合委托(delegate)并实现更新单元格的功能。
extension SelfSizingTableViewCell: CollectionViewSelfSizingDelegate {
func collectionView(_ collectionView: UICollectionView, didChageContentSizeFrom oldSize: CGSize, to newSize: CGSize) {
if let indexPath = indexPath {
tableView?.reloadRows(at: [indexPath], with: .none)
} else {
tableView?.reloadData()
}
}
}
请注意,我为 UIView
和 UITableViewCell
编写了一些辅助扩展来访问父 TableView :
extension UIView {
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
}
extension UITableViewCell {
var tableView: UITableView? {
return (next as? UITableView) ?? (parentViewController as? UITableViewController)?.tableView
}
var indexPath: IndexPath? {
return tableView?.indexPath(for: self)
}
}
至此,您的 Collection View 将具有完全需要的高度(如果它是垂直的),但您应该记住限制所有单元格的宽度,以免超出屏幕宽度。
extension SelfSizingTableViewCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: frame.width, height: heights[indexPath.row])
}
}
注意 heights
了吗?这是您应该缓存(手动/自动)所有单元格的计算高度的地方,以免变得迟钝。 (出于测试目的,我随机生成了所有这些)
最后两个步骤已经涵盖,但您应该考虑有关您寻求的案例的一些重要事项:
1 - 如果您要求 Autolayout 为您计算所有单元格大小,Autolayout 可能会成为史诗般的性能 killer ,但它是可靠的。
2 - 您必须缓存所有尺寸并获取最高尺寸并将其返回到 tableView(:,heightForRowAt:)
(不再需要自调整 tableViewCell
)
3 - 考虑到最高的那个可能比整个 tableView
还高,2D 滚动会很奇怪。
4 - 如果您重复使用包含 collectionView
或 tableView
的单元格,则滚动偏移、插入和许多其他属性的行为将以您不期望的方式出现。
这是您可能遇到的所有布局中最复杂的布局之一,但是一旦您习惯了它,它就会变得简单。
关于ios - 动态高度 UITableViewCell 内的动态高度 UICollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56318626/
我有下面的图表,它填充了显示器的宽度和高度。高度始终只比屏幕大一点,因此会出现滚动条以显示底部 20 像素左右。 有没有办法让 Kendo UI 显示 100%,而不是 105% 的高度? 在线示例:
这个问题在这里已经有了答案: Why doesn't height: 100% work to expand divs to the screen height? (12 个答案) 关闭 9 年前
此页面 ( http://purcraft.com/madeinla/) 有问题,我正在尝试使用 iframe 元素显示此页面的内容:( http://purcraft.com/madeinla/ho
我在一个父 div 中有 2 个子 div。 Child1 是标题,Child2 是正文。我希望将 Child 2 的高度设置为 Parent - Child1 的高度。 Child2 有内容,所以它
我正在尝试用图像填充窗口。我正在使用 CSS 来尝试解决这个问题,但我想知道是否有一种方法可以最大化图像的宽度/高度,直到所有空白区域都被填满,但又不会破坏质量。 .rel-img-co
这个问题在这里已经有了答案: How to make a div 100% height of the browser window (41 个回答) 关闭 8 年前。
这可能是一个新手问题,但是是否可以将 Sprite 图标添加到带有文本的标签中? 例如: labeltext .icon { width: 30px height: 30px;
我有 3 个 div,分别是 header、content 和 footer。页眉和页脚具有固定的高度,并且它们被设计为 float 在顶部和底部。我想要使用 jquery 自动计算中间的 con
我有一个外部 div,其指定的宽度/高度(以毫米为单位)。 (mm只是赋值,不用于渲染)。 里面有另一个 div,其实际宽度/高度(以 px 为单位)。 两个 div 可以具有不同的比例。 我想要做的
我正在为一个非常简单的画廊 webapp 进行布局排序,但是当我使用 HTML5 文档类型声明时,我的一些 div(100%)的高度会立即缩小,我不能似乎使用 CSS 将它们丰满起来。 我的 HTML
我正在为一个非常简单的画廊 webapp 进行布局排序,但是当我使用 HTML5 文档类型声明时,我的一些 div(100%)的高度会立即缩小,我不能似乎使用 CSS 将它们丰满起来。 我的 HTML
我想更改 UISearchBar。文本字段的高度和宽度。我的问题是如何更改 iphone 中 UISearchBar 中的 UiSearchbar 高度、宽度、颜色 和 Uitextfield 高度?
我想要两个宽度和高度均为 100% 的 div。我知道子 div 不会工作,因为父 div 没有特定的高度,但有没有办法解决这个问题? HTML: CSS: body
我有几个带有“priceText”类的 div,我试图实现如果 div.priceText 高度小于 100px,则隐藏 this div 中的图像。 我无法让它工作。我已成功隐藏所有 .priceT
我正在尝试从 Image 列中列出的图像中获取实际图像尺寸,并将其显示在 Image Size 列中。 我遇到的问题是,我只能获取第一张图片的大小,该图片会添加到 Image Size 列的每个单元格
我正在使用一个插件,它要求我在加载图像后获取图像的宽度和高度,而不管图像的尺寸是如何确定的。
我有一个示例 pdf(已附),它包括一个文本对象和一个高度几乎相同的矩形对象。然后我使用 itextrup 检查了 pdf 的内容,如下所示: 1 1 1 RG 1 1 1 rg 0.12 0 0 0
我是 WPF 新手。我试图解决的一个问题是如何在运行时获得正确的高度。 在我的应用程序中,我将用户控件动态添加到代码隐藏中的 Stackpanel。 Usercontrol 包含一些 Texblock
在自定义 WPF 控件中,我想将控件的宽度设置为高度的函数。例如:Width = Height/3 * x; 实现此目的的最佳方法是什么,以便控件正确且流畅地调整大小(和初始大小)? 最佳答案 您可以
好吧,我本以为这是一个简单的问题,但显然它让我感到困惑。 当我尝试设置 RibbonComboBox 的高度时,它不会移动它的实际大小,而是移动它周围的框。 这是我的 XAML:
我是一名优秀的程序员,十分优秀!