代码之家  ›  专栏  ›  技术社区  ›  Cœur Gustavo Armenta

缩放的UIPageControl点未居中

  •  0
  • Cœur Gustavo Armenta  · 技术社区  · 6 年前

    我对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) 没有效果。
    • 更改约束 like here

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

      enter image description here

    0 回复  |  直到 6 年前
        1
  •  5
  •   Cœur Gustavo Armenta    5 年前

    我终于重写了 全部的 子视图由我自己约束。

    // 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))
                ])
            }
        }
    }
    

    result

        2
  •  0
  •   Finetuning-mg    5 年前

    我尝试了由 Cœur 在Swift 5和Xcode 11中,它可以很好地处理一些注释:

    • IB/Storyboard中的PageControl元素必须使用约束进行定位。
    • 点稍微偏离中心,但可以通过将最后一个约束的常数更改为 systemDotDistance * ( CGFloat($0.offset) - (halfCount - 0.5))
    • 如果 updateConstraints 覆盖从未调用,您可能需要调用 self.view.setNeedsUpdateConstraints()