缩放 UIPageControl 的当前点并保持居中

Scaling current dot of UIPageControl and keeping it centered

我已经将 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
            [=10=].transform = [=10=] == currentDot ? largeScaling : .identity
        }
    }
}

但是转换的结果没有居中(红点应该与其他点对齐):

我试过了(在 iOS 12):

我通过自己重写 所有 子视图约束终于让它工作了。

// 
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.
            [=10=].transform = [=10=] == 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 = [=10=].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([=10=].offset) - halfCount))
            ])
        }
    }
}

代码中的系统常量(7.0 和 16.0)分别是 iOS 12 上默认 UIPageControl 点的大小和距离。

我尝试了 Cœur 在 Swift 5 和 Xcode 11 中提出的解决方案,它在一些注释下工作正常:

  • IB/Storyboard 中的 PageControl 元素必须使用约束进行定位。
  • 这些点稍微偏离中心,但可以通过将最后一个约束的常量更改为 systemDotDistance * ( CGFloat([=10=].offset) - (halfCount - 0.5)).
  • 来快速修复
  • 如果从未调用 updateConstraints 覆盖,您可能需要在视图控制器中调用 self.view.setNeedsUpdateConstraints()