Skip to content

Commit

Permalink
Fix content inset
Browse files Browse the repository at this point in the history
  • Loading branch information
KyoheiG3 committed Jan 30, 2017
1 parent 8e84834 commit c420958
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
19 changes: 15 additions & 4 deletions GridView/GridView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ open class GridView: UIScrollView {
get { return originContentInset }
set { originContentInset = newValue }
}
private var originScrollIndicatorInsets: UIEdgeInsets = .zero
override open var scrollIndicatorInsets: UIEdgeInsets {
get { return originScrollIndicatorInsets }
set { originScrollIndicatorInsets = newValue }
}

// MARK: Overrides
override init(frame: CGRect) {
Expand All @@ -109,7 +114,9 @@ open class GridView: UIScrollView {
}

override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return CGRect(origin: .zero, size: contentSize).contains(point)
let origin = CGPoint(x: -contentInset.left, y: -contentInset.top)
let size = CGSize(width: contentSize.width + contentInset.horizontal, height: contentSize.height + contentInset.vertical)
return CGRect(origin: origin, size: size).contains(point)
}

open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
Expand All @@ -132,7 +139,7 @@ open class GridView: UIScrollView {
withoutScrollDelegation = false

let contentWidth = self.contentWidth ?? currentViewBounds.width
if contentWidth != bounds.width || contentWidth != currentViewBounds.width {
if contentWidth != bounds.width || contentWidth != currentViewBounds.width || bounds.size != currentViewBounds.size {
if let width = self.contentWidth {
bounds.size.width = width
}
Expand All @@ -144,7 +151,7 @@ open class GridView: UIScrollView {

if let superview = superview {
let inset = UIEdgeInsets(top: -frame.minY, left: -frame.minX, bottom: -superview.bounds.height + frame.maxY, right: -superview.bounds.width + frame.maxX)
scrollIndicatorInsets = inset
super.scrollIndicatorInsets = inset + originScrollIndicatorInsets
}

if needsLayout == .none {
Expand Down Expand Up @@ -177,7 +184,11 @@ open class GridView: UIScrollView {
performWithoutDelegation {
contentSize = currentMatrix.contentSize
}

withoutScrollDelegation = type.isScaling
contentOffset = currentMatrix.convert(lastValidityContentOffset, from: type.matrix)
withoutScrollDelegation = false

super.contentInset = currentMatrix.contentInset

if case .pinching = type {
Expand Down Expand Up @@ -403,7 +414,7 @@ extension GridView {
let matrix = currentMatrix
newOffset = CGPoint(x: contentOffset.x + frame.minX + matrix.validityContentRect.minX, y: contentOffset.y + frame.minY + matrix.validityContentRect.minY)
} else {
newOffset = contentOffset
newOffset = CGPoint(x: contentOffset.x + frame.minX, y: contentOffset.y + frame.minY)
}

super.setContentOffset(newOffset, animated: animated)
Expand Down
8 changes: 8 additions & 0 deletions GridView/UIEdgeInsetsExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@ extension UIEdgeInsets {
static func -(lhs: UIEdgeInsets, rhs: UIEdgeInsets) -> UIEdgeInsets {
return UIEdgeInsets(top: lhs.top - rhs.top, left: lhs.left - rhs.left, bottom: lhs.bottom - rhs.bottom, right: lhs.right - rhs.right)
}

var horizontal: CGFloat {
return left + right
}

var vertical: CGFloat {
return top + bottom
}
}
13 changes: 8 additions & 5 deletions GridView/ViewMatrix.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@ struct ViewMatrix: Countable {
func convert(_ offset: CGPoint, from matrix: ViewMatrix) -> CGPoint {
let oldContentOffset = offset + matrix.viewFrame.origin
let indexPath = matrix.indexPathForRow(at: oldContentOffset)

let oldRect = matrix.rectForRow(at: indexPath)
let newRect = rectForRow(at: indexPath)
let oldOffset = oldContentOffset - oldRect.origin
guard oldRect.width != 0 && oldRect.height != 0 else { return .zero }

let newRect = rectForRow(at: indexPath)
let newOffset = CGPoint(x: newRect.width * oldOffset.x / oldRect.width, y: newRect.height * oldOffset.y / oldRect.height)
let viewOrigin = rectForRow(at: indexPath).origin
let contentOffset = viewOrigin + newOffset

let contentOffset = newRect.origin + newOffset

let actualSize: CGSize = contentSize - (visibleSize ?? .zero)
let maxOrigin = CGPoint(x: viewFrame.origin.x + inset.right + actualSize.width, y: viewFrame.origin.y + inset.bottom + actualSize.height)
let maxOffset = CGPoint(x: viewFrame.origin.x + inset.right + actualSize.width, y: viewFrame.origin.y + inset.bottom + actualSize.height)
let minOffset = CGPoint(x: viewFrame.origin.x - inset.left, y: viewFrame.origin.y - inset.top)
return min(max(contentOffset, minOffset), maxOrigin)
return min(max(contentOffset, minOffset), maxOffset)
}

init() {
Expand Down
11 changes: 11 additions & 0 deletions GridViewTests/UIEdgeInsetsExtensionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,15 @@ class UIEdgeInsetsExtensionTests: XCTestCase {
XCTAssertEqual(inset2 - inset1, UIEdgeInsets(top: -20, left: -40, bottom: -60, right: -80))
XCTAssertEqual(inset2 - inset2, .zero)
}

func testHorizontal() {
let inset1 = UIEdgeInsets(top: 10, left: 20, bottom: 30, right: 40)
let inset2 = UIEdgeInsets(top: -10, left: -20, bottom: -30, right: -40)

XCTAssertEqual(inset1.horizontal, 60)
XCTAssertEqual(inset2.horizontal, -60)

XCTAssertEqual(inset1.vertical, 40)
XCTAssertEqual(inset2.vertical, -40)
}
}

0 comments on commit c420958

Please sign in to comment.