Я пытаюсь создать пользовательское верхнее меню, которое имеет движущуюся оранжевую полосу изменения размера, которая обозначает, какая вкладка выбрана.Это очень распространенный дизайн, и я просто делаю это для практики, так как я новичок в Swift.Вы можете перемещаться, пролистывая нижний collectionView или вы можете выбрать вкладку в верхнем меню.Верхнее меню также является просто collectionView и также доступно для прокрутки.
Как вы можете видеть ниже (первый рисунок), моя проблема в том, что когда я пытаюсь вернуться на первую вкладку, проведя пальцем по нижней части или выбрав верхнюю, оранжевая полоса не перемещается клевый край экрана, как и ожидалось.Все остальное работает отлично.Тем не менее, когда я включаю отладчик и вставляю точки останова (второй gif), оранжевая полоса снова работает, как и ожидалось.
Я предполагаю, что это как-то связано с порядком обновления представлений или чем-то ещеделать с моментом, когда заканчивается анимация прокрутки.И это должно влиять на то, как я вычисляю положение оранжевой полосы.Вот почему, когда отладчик включен, а анимация замедлена, оранжевая полоса ведет себя как положено.Однако, поскольку я довольно неопытный, я не уверен, как точно определить проблему.
Моя реализация переопределяет scrollViewDidScroll
представления нижнего содержимого, проверяя, прокрутил ли пользователь больше половинытекущая страница.Если да, то вызовите topMenu.collectionView.setContentOffset
, чтобы прокрутить верхнее меню до его правильного положения, а также вызовите animateHorizontalBar(index: Int)
, как показано ниже, который принимает индекс целевой страницы.
К вашему сведению: array
просто содержит строки для заголовка каждой вкладки.Я использую размер строк для расчета размера и положения оранжевой полосы.
РЕДАКТИРОВАТЬ: Переход к первому индексу вполне подойдет, когда я отключил эту функцию, когда будет следовать горизонтальная полосавыбранная вкладка при прокрутке верхнего меню (второй рисунок)
Любая помощь будет принята с благодарностью.Спасибо!
func moveHorizontalBar(index: Int) {
let horizontalBar = topMenu.horizontalBarView
var sizeArray: [CGFloat] = []
for item in array {
sizeArray.append((ceil(40 + (item as NSString).size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.medium)]).width)))
}
let width = self.view.frame.width
let ratio = (topMenu.collectionView.contentSize.width - width) / (collectionView.contentSize.width - width)
let offset = CGFloat(index) * width * ratio
if index == 0 {
horizontalBar.frame.origin.x = 0.0
horizontalBar.frame.size.width = sizeArray[index]
} else {
var x: CGFloat = 0.0
for i in 0..<index {
x += sizeArray[i]
}
topMenu.currentOffset = x
horizontalBar.frame.origin.x = x - offset
horizontalBar.frame.size.width = sizeArray[index]
}
}
func animateHorizontalBar(index: Int, animated: Bool) {
if animated {
self.topMenu.isSelectingNewTab = true
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.moveHorizontalBar(index: index)
})
} else {
moveHorizontalBar(index: index)
}
}