Skip to content

Commit

Permalink
add a content inset setter helper
Browse files Browse the repository at this point in the history
  • Loading branch information
lkzhao committed Oct 30, 2024
1 parent 2d10fad commit bc1d1b2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ extension UIView {
_ = UIView.swizzle_layoutSubviews
_ = UIView.swizzle_sizeThatFits
_ = UIScrollView.swizzle_safeAreaInsetsDidChange
_ = UIScrollView.swizzle_setContentInset
_componentEngine = componentEngine
return componentEngine
}
Expand Down Expand Up @@ -69,7 +70,7 @@ extension UIView {
}

static let swizzle_setBounds: Void = {
guard let originalMethod = class_getInstanceMethod(UIView.self, NSSelectorFromString("setBounds:")),
guard let originalMethod = class_getInstanceMethod(UIView.self, #selector(setter: bounds)),
let swizzledMethod = class_getInstanceMethod(UIView.self, #selector(swizzled_setBounds(_:)))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
Expand All @@ -89,12 +90,39 @@ extension UIScrollView {
method_exchangeImplementations(originalMethod, swizzledMethod)
}()

static let swizzle_setContentInset: Void = {
guard let originalMethod = class_getInstanceMethod(UIScrollView.self, #selector(setter: contentInset)),
let swizzledMethod = class_getInstanceMethod(UIScrollView.self, #selector(swizzled_setContentInset(_:)))
else { return }
method_exchangeImplementations(originalMethod, swizzledMethod)
}()

@objc func swizzled_safeAreaInsetsDidChange() {
guard responds(to: #selector(swizzled_safeAreaInsetsDidChange)) else { return }
swizzled_safeAreaInsetsDidChange()
if let componentEngine = _componentEngine, contentInsetAdjustmentBehavior != .never {
componentEngine.setNeedsReload()
}
}

@objc func swizzled_setContentInset(_ contentInset: UIEdgeInsets) {
// when contentOffset is at the top, and contentSize is set
// changing contentInset will not trigger a contentOffset change
// we manually adjust the contentOffset back to the top
// same for the horizontal axis
let yAtTop = contentOffset.y <= -adjustedContentInset.top
let xAtLeft = contentOffset.x <= -adjustedContentInset.left
swizzled_setContentInset(contentInset)
var newContentOffset = contentOffset
if yAtTop {
newContentOffset.y = -adjustedContentInset.top
}
if xAtLeft {
newContentOffset.x = -adjustedContentInset.left
}
if newContentOffset != contentOffset {
contentOffset = newContentOffset
}
}
}

15 changes: 5 additions & 10 deletions Sources/UIComponent/Extensions/UIScrollView+UIComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,12 @@ extension UIScrollView {
}

public var offsetFrame: CGRect {
let contentInset: UIEdgeInsets
if #available(iOS 11.0, *) {
contentInset = adjustedContentInset
} else {
contentInset = self.contentInset
}
let inset = adjustedContentInset
return CGRect(
x: -contentInset.left,
y: -contentInset.top,
width: max(0, contentSize.width - bounds.width + contentInset.right + contentInset.left),
height: max(0, contentSize.height - bounds.height + contentInset.bottom + contentInset.top)
x: -inset.left,
y: -inset.top,
width: max(0, contentSize.width - bounds.width + inset.right + inset.left),
height: max(0, contentSize.height - bounds.height + inset.bottom + inset.top)
)
}

Expand Down

0 comments on commit bc1d1b2

Please sign in to comment.