Skip to content
This repository has been archived by the owner on Aug 16, 2019. It is now read-only.

Commit

Permalink
FIX calulcation of targetOffset
Browse files Browse the repository at this point in the history
ADD support for animated flag
ADD started with writing Snapshot test - WIP
ADD Snapshot for Snapshot test, but current snapshot is not waht we want
  • Loading branch information
AndreasThenn committed Mar 10, 2017
1 parent 60eba94 commit 321d7a3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
15 changes: 9 additions & 6 deletions Source/Views/StackViewController.swift
Expand Up @@ -85,7 +85,7 @@ final class StackViewController: UIViewController {
/// the stackViews' orientation some relativePosition values have different meaning:
/// beginning - top/left, end - bottom/right
public func scrollToViewController(target targetViewController: UIViewController,
position relativePosition: RelativePosition = .center) {
position relativePosition: RelativePosition = .center, animated: Bool = false) {

guard self.childViewControllers.contains(targetViewController) else {
return
Expand All @@ -95,6 +95,7 @@ final class StackViewController: UIViewController {
let targetFrame = targetViewController.view.frame

if stackView.axis == .vertical {
// keep current horizontal offset
targetOffset.x = -scrollView.contentInset.left
let topOffset = targetFrame.origin.y - scrollView.contentInset.top
let bottomOffset = targetFrame.origin.y + targetFrame.height - scrollView.bounds.height
Expand All @@ -104,29 +105,31 @@ final class StackViewController: UIViewController {
targetOffset.y = topOffset
break
case .center:
targetOffset.y = topOffset - bottomOffset - (targetFrame.height / 2)
targetOffset.y = topOffset - (topOffset - bottomOffset) / 2
break
case .end:
targetOffset.y = bottomOffset
break
}
} else {
// keep current vertical offset
targetOffset.y = -scrollView.contentInset.top
let leftOffset = targetFrame.origin.x - scrollView.contentInset.left
let rightOffset = targetFrame.origin.x + targetFrame.width - scrollView.bounds.width

switch relativePosition {
case .beginning:
targetOffset.x = targetFrame.origin.x - scrollView.contentInset.left
targetOffset.x = leftOffset
break
case .center:
targetOffset.x = -(targetOffset.x - rightOffset - (targetFrame.width / 2))
targetOffset.x = leftOffset - (leftOffset - rightOffset) / 2
break
case .end:
targetOffset.x = rightOffset
break
}
}
scrollView.setContentOffset(targetOffset, animated: true)

scrollView.setContentOffset(targetOffset, animated: animated)
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions Tests/StackClusterTests.swift
Expand Up @@ -136,6 +136,40 @@ class StackClusterTests: QuickSpec {
expect(scrollView).toNot(scroll(.horizontal))
}

context("scroll into view target can be positioned as wanted") {
let size = CGSize(width: 300, height: 300)
let children = [
labelComponent(title: "1", color: .purple, labelSize: size),
labelComponent(title: "2", color: .red, labelSize: size),
labelComponent(title: "3", color: .yellow, labelSize: size),
labelComponent(title: "4", color: .green, labelSize: size),
labelComponent(title: "5", color: .green, labelSize: size)
]

it("should be able to scroll horizontally to target") {
let meta = ClusterLayout.StackConfig(axis: .horizontal)
let vc = stack(with: children, meta: meta)
vc?.loadViewIfNeeded()
// let scrollView = vc?.stackView.superview as? UIScrollView
let targetVC = vc?.childViewControllers[2]

// WIP does not scroll at all, with or wothout dispatcher and setting the offset manually in scroll method
let exp = self.expectation(description: "wait for scrolling")
vc?.scrollToViewController(target: targetVC!, position: .center, animated: false)

DispatchQueue.main.asyncAfter(deadline: (.now() + 3)) {

exp.fulfill()
}

self.waitForExpectations(timeout: 5, handler: nil)

// expect(vc).to(recordSnapshot())
// expect(scrollView).to(scroll(.horizontal))
// expect(scrollView).toNot(scroll(.vertical))
}
}

context("when a horizontal stack is contained in a vertical stack") {

let nestedStack: () -> StackViewController? = {
Expand Down

3 comments on commit 321d7a3

@AndreasThenn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MP0w Can you tell me why line 2 fails, if I comment line 1 out? (in your test should be able to scroll horizontally above)
expect(vc).to(haveValidSnapshot())
expect(scrollView).to(scroll(.horizontal))
expect(scrollView).toNot(scroll(.vertical))

@AndreasThenn
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx to @ChristianOrgler, we found the answer.
The view has to be layout first, that's why we have to call view.layoutIfNeeded() before we can take correct snapshots for the scrolling tests. I will add this to some of your tests, too. That way some expectations do not rely on taking a snapshot first.

@MP0w
Copy link
Contributor

@MP0w MP0w commented on 321d7a3 Mar 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I wonder if we can do all without any calculation: you get a CGPoint using minX/Y maxX/Y or mid and then use the UiView method to convert that point to the stack's space

Please sign in to comment.