Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll indicators update - positioning correction, support for both indicators at the same time #229

Open
wants to merge 98 commits into
base: master
Choose a base branch
from

Conversation

janek
Copy link
Contributor

@janek janek commented Jun 14, 2018

Corrects positioning, adds configurable indicator insets, adds conditional positioning when one/both indicators are visible.

Type of change: Bug fix + feature

Todos

  • corrected positioning
  • added support for both indicators at the same time
  • implemented default/base apple inset values
  • added support for configurable scrollIndicatorInsets (as per apple docs)
  • fixed other subviews of UIScrollView being added in front of indicators

Expected behavior

Scroll indicators should now position and style themselves in a way indistinguishable from Apple's.

Testing Details

Tested visually on NativePlayer with some additional marker views for better confidence.
Tested with a smaller dedicated app, both visually and numerically.

Screenshots

Current (desired) positioning of indicators:

screenshot 2019-03-05 at 13 58 14

Please check if the PR fulfills these requirements

  • Self-review: I am confident this is the simplest and clearest way to achieve the expected behaviour
  • There are no dependencies on other PRs or I have linked dependencies through Zenhub
  • The commit messages are clean and understandable
  • Tests for the changes have been added (for bug fixes / features)
  • Code runs on all relevant platforms (if major change: screenshots attached)

@janek janek added the WIP label Jun 14, 2018
@janek janek force-pushed the scroll-indicators-update branch from be4e9de to 38a274b Compare June 29, 2018 13:45
@janek janek force-pushed the scroll-indicators-update branch from 38a274b to 9f1538c Compare June 29, 2018 13:55
@janek janek changed the title Scroll indicators update - adding scrollIndicatorsInsets Scroll indicators update - positioning correction, support for both indicators at the same time Jun 29, 2018
@janek janek removed the WIP label Jul 1, 2018
@janek janek requested a review from ephemer July 7, 2018 13:47
@codecov
Copy link

codecov bot commented Feb 17, 2020

Codecov Report

Merging #229 into master will increase coverage by 0.71%.
The diff coverage is 97.59%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #229      +/-   ##
==========================================
+ Coverage   52.15%   52.86%   +0.71%     
==========================================
  Files          87       87              
  Lines        3160     3210      +50     
==========================================
+ Hits         1648     1697      +49     
- Misses       1512     1513       +1     
Impacted Files Coverage Δ
Sources/UIScrollView.swift 90.90% <92.85%> (+2.02%) ⬆️
Sources/UIScrollView+indicatorsInternal.swift 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8f10d29...6a899ae. Read the comment docs.

@janek
Copy link
Contributor Author

janek commented Feb 18, 2020

hey @ephemer :) I improved a lot here, addressing all the smaller comments you had.

Unfortunately, I still have a concern:

if you check scrollView.subviews on iOS, it will not include scroll indicators. In our version, in the state from this PR, it will include them. We can address this here or with a new issue, depending on how demanding/important it is. I gave it a moment's thought and decided it's best to ask you for opinion before trying, and a tip on how to go about it.

@janek janek requested a review from ephemer February 18, 2020 16:55
@ephemer
Copy link
Member

ephemer commented Feb 18, 2020

@janek we could override var subviews to return a filtered version of private var _subviews = [UIView]. It's tricky though because AFAIK we're using subviews for some "internal" UIKit logic, which may or may not be correct.

But to me that's an issue that's totally separate from this PR. If you would like to update that let's do it for a practical (rather than idealistic) reason: right now I don't think it matters for us

@janek
Copy link
Contributor Author

janek commented Feb 18, 2020

cool, that's what I was thinking, too, for the implementation. Glad I had the right idea (and the right idea to ask).

In that case, this is ready for re-review.

Copy link
Member

@ephemer ephemer left a comment

Choose a reason for hiding this comment

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

Hi @janek, code-wise the library code seems fine but the tests are very shonky as is.

The tests contain false assumptions and hardcoded outdated values which don't mean anything. Sometimes we're calling an identical assertion twice (what's the point in calling XCTAssertEqual on two static values twice?), even though the second time the reality is that the underlying values have changed. It's not up to scratch as written.

Please try to rewrite the new tests in more finer-grained ones that test one thing, that are clearly named so it's obvious what to fix if they break, that don't rely on hardcoded values if possible, and that test the absolute minimal amount possible while still ensuring behaviour. And please be careful to get the new indexes after changing the order of an array.

let indexOfInsertedView2 = scrollView.subviews.index(of: viewToBeInserted1)!

// If we try to insert at a position occupied by or above indicators,
// the inserted view should 'slide down' and assume the highest position below indicators
Copy link
Member

Choose a reason for hiding this comment

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

nice, these comments are helpful thanks!

Copy link
Member

Choose a reason for hiding this comment

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

but this should just be its own standalone test. it tests one single behaviour that obviously must be true. if we insert a subview it should always be behind the indicators. end of test. if that breaks we know what to fix. does that make sense?

let indexOfInsertedView1 = scrollView.subviews.index(of: viewToBeInserted1)!

// This might seem weird, but that's what happens in iOS:
// the inserted view and the one that was in its place before will have the same index
Copy link
Member

Choose a reason for hiding this comment

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

is it possible this is only weird because of how the test is written?

It doesn't seem that weird to me that the indexes will overlap once we insert a new subview if we're not getting the new indexes after inserting the subview?

What am I missing here? It seems like we should get the new indexes here which would be less confusing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're not missing anything, I can't believe I missed this! 🤦‍♂ thanks!

samples/getting-started/DemoApp/ViewController.swift Outdated Show resolved Hide resolved
samples/getting-started/DemoApp/ViewController.swift Outdated Show resolved Hide resolved


let viewToBeInserted2 = UIView()
scrollView.insertSubview(viewToBeInserted2, at: 5) // position currently occupied by scroll indicator
Copy link
Member

Choose a reason for hiding this comment

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

this test is too long. this could be two or three separate tests which would be much clearer if one of them fails

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for this and all the other very valid concerns. I rewrote the test(s) in a way that hopefully takes into account all of them.

XCTAssertEqual(indexOfInsertedView1, 1)
XCTAssertEqual(label2Index, 1)
XCTAssertEqual(label3Index, 2)
XCTAssertEqual(horizontalIndicatorIndex, 3)
Copy link
Member

Choose a reason for hiding this comment

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

This is misleading at best: all of these indexes will be incorrect now, so what's the point in asserting what their old value was? I'm really not happy with this, as written


XCTAssert(label2Index > label1Index)

XCTAssertEqual(label1Index, 0)
Copy link
Member

Choose a reason for hiding this comment

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

what's the point in adding three subviews? we already have other tests that test the behaviour of addSubview. we're just writing more test code that we have to maintain.

how is this different to the case at the bottom?

let label2Index = scrollView.subviews.index(of: view2)!
let label3Index = scrollView.subviews.index(of: view3)!

XCTAssert(horizontalIndicatorIndex > label1Index)
Copy link
Member

Choose a reason for hiding this comment

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

how is this different to the case at the bottom?


let horizontalIndicatorIndex = scrollView.subviews.index(of: scrollView.horizontalScrollIndicator)!
let verticalIndicatorIndex = scrollView.subviews.index(of: scrollView.verticalScrollIndicator)!
let label1Index = scrollView.subviews.index(of: view1)!
Copy link
Member

Choose a reason for hiding this comment

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

I don't think it makes sense to put this into a variable, because (as mentioned below) it will be invalid as soon as we insert another view.

XCTAssertGreaterThan(
    scrollView.subviews.index(of: scrollView.horizontalScrollIndicator),
    scrollView.subviews.index(of: view1)
)

@janek janek requested a review from ephemer February 19, 2020 17:12
@janek
Copy link
Contributor Author

janek commented Feb 24, 2020

thanks @ephemer! I didn't reply to all of your comments, but I took them into account when rewriting tests. It's definitely a big improvement, and I'm quite happy. Also very happy to perfect them if there is anything else that you see could be improved :)

Copy link
Member

@ephemer ephemer left a comment

Choose a reason for hiding this comment

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

Awesome! I am stoked with how great these new tests you wrote are looking now! Thanks for your work on this @janek

scrollView.addSubview(mockView)

XCTAssertGreaterThan(
scrollView.subviews.index(of: scrollView.horizontalScrollIndicator)!,
Copy link
Member

Choose a reason for hiding this comment

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

These tests look seriously amazing now. Great work @janek!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's too nice! thanks a lot!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants