Skip to content

Commit

Permalink
Breaking content: UIView retain cycle in UIViewLazyList's LazyListCon…
Browse files Browse the repository at this point in the history
…tainerCell (#2250)

The content view is a Swift object, so it needs to be manually nil'd out by its Kotlin retainer
  • Loading branch information
dnagler authored Aug 19, 2024
1 parent 6e80cd9 commit 6d37ac7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Changed:
- Change `UiConfiguration.viewportSize` to be nullable. A null `viewportSize` indicates the viewport's size has not been resolved yet.

Fixed:
- Nothing yet!
- Breaking `content: UIView` retain cycle in `UIViewLazyList`'s `LazyListContainerCell`.


## [0.13.0] - 2024-07-25
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ internal open class UIViewLazyList :
}

override fun setContent(view: LazyListContainerCell, content: UIView?, modifier: Modifier) {
view.content = content
view.setContent(content)
}
}

Expand Down Expand Up @@ -269,16 +269,6 @@ internal class LazyListContainerCell(
reuseIdentifier: String?,
) : UITableViewCell(style, reuseIdentifier) {
internal var binding: Binding<LazyListContainerCell, UIView>? = null
internal var content: UIView? = null
set(value) {
field = value

removeAllSubviews()
if (value != null) {
contentView.addSubview(value)
}
setNeedsLayout()
}

override fun initWithStyle(
style: UITableViewCellStyle,
Expand Down Expand Up @@ -320,13 +310,26 @@ internal class LazyListContainerCell(
override fun layoutSubviews() {
super.layoutSubviews()

val content = this.content ?: return
if (contentView.subviews.isEmpty()) return

val content = contentView.subviews.first() as UIView ?: return
content.setFrame(bounds)
contentView.setFrame(bounds)
}

override fun sizeThatFits(size: CValue<CGSize>): CValue<CGSize> {
return content?.sizeThatFits(size) ?: return super.sizeThatFits(size)
if (contentView.subviews.isEmpty()) return super.sizeThatFits(size)

val content = contentView.subviews.first() as UIView ?: return super.sizeThatFits(size)
return content.sizeThatFits(size)
}

internal fun setContent(content: UIView?) {
removeAllSubviews()
if (content != null) {
contentView.addSubview(content)
}
setNeedsLayout()
}

private fun removeAllSubviews() {
Expand Down

0 comments on commit 6d37ac7

Please sign in to comment.