缩放UIPageControl的当前点并使其居中

时间:2019-03-08 09:39:58

标签: ios swift uikit uipagecontrol

我将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的{​​{1}}或center无效。
  • 将转换更改为包含currentDot无效。
  • 改变约束like here使得第一个点跳了起来:

    translatedBy(x: CGFloat, y: CGFloat)

    enter image description here

2 个答案:

答案 0 :(得分:1)

我最终通过自己重写 all 子视图约束来使它正常工作。

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

    override var currentPage: Int {
        didSet {
            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)分别是iOS 12上默认UIPageControl点的大小和距离。

result

答案 1 :(得分:0)

我尝试了Cœur在Swift 5和Xcode 11中提出的解决方案,它在运行时仅需注意以下几点:

  • IB / Storyboard中的PageControl元素必须放置约束。
  • 点稍微偏心,但是可以通过将最后一个约束的常数更改为getDbConfig()来快速固定。
  • 如果从未调用过systemDotDistance * ( CGFloat($0.offset) - (halfCount - 0.5))覆盖,则可能需要在视图控制器中调用updateConstraints