Масштабирование текущей точки UIPageControl и удержание ее по центру - PullRequest
1 голос
/ 08 марта 2019

Я подклассифицировал UIPageControl, чтобы его текущая точка была больше.

class CustomPageControl: UIPageControl {
    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }

    func updateDots() {
        let currentDot = subviews[currentPage]
        let largeScaling = CGAffineTransform(scaleX: 3, y: 3)

        subviews.forEach {
            // apply the large scale of newly selected dot
            // restore the normal scale of previously selected dot
            $0.transform = $0 == currentDot ? largeScaling : .identity
        }
    }
}

Но результат преобразования не центрирован (красная точка должна быть выровнена с остальными):
enter image description here

Я пробовал (на iOS 12):

  • изменение frame или center из currentDot не имеет никакого эффекта.
  • изменение преобразования для включения translatedBy(x: CGFloat, y: CGFloat) не имеет никакого эффекта.
  • изменение ограничений как здесь делает первый прыжок с точкой:

    currentDot.translatesAutoresizingMaskIntoConstraints = false
    currentDot.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0)
    currentDot.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0)
    

    enter image description here

1 Ответ

2 голосов
/ 08 марта 2019

Я наконец-то заработал, переписав все ограничения на подпредставления самостоятельно.

// https://stackoverflow.com/a/55063316/1033581
class DefaultPageControl: UIPageControl {

    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }

    override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        super.sendAction(action, to: target, for: event)
        updateDots()
    }

    private func updateDots() {
        let currentDot = subviews[currentPage]
        let largeScaling = CGAffineTransform(scaleX: 3.0, y: 3.0)
        let smallScaling = CGAffineTransform(scaleX: 1.0, y: 1.0)

        subviews.forEach {
            // Apply the large scale of newly selected dot.
            // Restore the small scale of previously selected dot.
            $0.transform = $0 == currentDot ? largeScaling : smallScaling
        }
    }

    override func updateConstraints() {
        super.updateConstraints()
        // We rewrite all the constraints
        rewriteConstraints()
    }

    private func rewriteConstraints() {
        let systemDotSize: CGFloat = 7.0
        let systemDotDistance: CGFloat = 16.0

        let halfCount = CGFloat(subviews.count) / 2
        subviews.enumerated().forEach {
            let dot = $0.element
            dot.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.deactivate(dot.constraints)
            NSLayoutConstraint.activate([
                dot.widthAnchor.constraint(equalToConstant: systemDotSize),
                dot.heightAnchor.constraint(equalToConstant: systemDotSize),
                dot.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0),
                dot.centerXAnchor.constraint(equalTo: centerXAnchor, constant: systemDotDistance * (CGFloat($0.offset) - halfCount))
            ])
        }
    }
}

Системные константы в коде (7.0 и 16.0) - соответственно размер и расстояние, найденное для точки UIPageControl по умолчанию на iOS 12.

result

...