HorizonCalendar icon indicating copy to clipboard operation
HorizonCalendar copied to clipboard

Display Glitches When Performing Push Transition Without Scroll Animation

Open ryoooooory opened this issue 1 year ago • 0 comments

Hey! This library is so easy to use, rich and awesome!

I was exploring the "HorizonCalendar Example App" and came across a bug that I wanted to share.

[bug] In screens where there are push transitions without scroll animations (e.g., LargerDayRangeDemoViewController), the display is briefly disrupted. Specifically, scrolling occurs without animation before the screen is fully displayed, which leads to a part of the calendar becoming visible in the navigation section right before the transition completes. https://github.com/airbnb/HorizonCalendar/assets/34418898/915eeb7b-772c-46f1-b7d2-b7d01d229a81

[Testing] iPhone14 simulator iOS 16.4

[Probable cause] The NoContentInsetAdjustmentScrollView, used in the CalendarView, has its contentInsetAdjustmentBehavior set to .never in the init(). Because of this, the Safe Area doesn't seem to be considered immediately. As a result, the blur effect under the navigation area doesn't cover the Calendar View initially, allowing a part of the Calendar View to be briefly visible under the navigation area.

[solution] I managed to solve the issue by delaying the scroll timing slightly and by not setting contentInsetAdjustmentBehavior to .never. The specific changes are as follows:"

Specifically, they are as follows

final class LargeDayRangeDemoViewController: BaseDemoViewController {
// scroll timing shift(viewWillLayoutSubviews -> viewDidAppear)
override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        guard !didScrollToInitialMonth else { return }

        let padding: CGFloat
        switch monthsLayout {
        case .vertical: padding = calendarView.layoutMargins.top
        case .horizontal: padding = calendarView.layoutMargins.left
        }

        let january1500CE = calendar.date(from: DateComponents(era: 1, year: 1500, month: 01, day: 01))!
        calendarView.scroll(
            toMonthContaining: january1500CE,
            scrollPosition: .firstFullyVisiblePosition(padding: padding),
            animated: false)

        didScrollToInitialMonth = true

    }
}

public final class CalendarView: UIView {
// contentInsetAdjustmentBehavior  != .never, can be anything.(NoContentInsetAdjustmentScrollView -> UIScrollView)
fileprivate lazy var scrollView: UIScrollView = {
    let scrollView = UIScrollView()
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false
    scrollView.delegate = scrollViewDelegate
    return scrollView
  }()
}

I would also like to submit a pull request with the changes that fixed this issue. If you're interested, I can prepare that for you. Thanks!!

ryoooooory avatar Jul 02 '23 17:07 ryoooooory