自定义PageControl图像 - Swift

时间:2017-11-14 06:36:21

标签: ios swift pagecontrol

我正在尝试为UIPageControl点设置图像。

我需要更改默认点,而不是我需要图像。 我使用下面的代码

self.pageCtrl.currentPageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "Page Indicator_Selected")!)
self.pageCtrl.pageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "Page Indicator_Normal")!)

我可以在Pagecontrol中设置图像,但它与默认点重叠。

4 个答案:

答案 0 :(得分:3)

我改进了Agent Smith的答案,可以处理任意数量的页面。您可以在xib / storyboard上自定义图像。

class CustomPageControl: UIPageControl {

@IBInspectable var currentPageImage: UIImage?

@IBInspectable var otherPagesImage: UIImage?

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

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

override func awakeFromNib() {
    super.awakeFromNib()
    pageIndicatorTintColor = .clear
    currentPageIndicatorTintColor = .clear
    clipsToBounds = false
}

private func updateDots() {

    for (index, subview) in subviews.enumerated() {
        let imageView: UIImageView
        if let existingImageview = getImageView(forSubview: subview) {
            imageView = existingImageview
        } else {
            imageView = UIImageView(image: otherPagesImage)

            imageView.center = subview.center
            subview.addSubview(imageView)
            subview.clipsToBounds = false
        }
        imageView.image = currentPage == index ? currentPageImage : otherPagesImage
    }
}

private func getImageView(forSubview view: UIView) -> UIImageView? {
    if let imageView = view as? UIImageView {
        return imageView
    } else {
        let view = view.subviews.first { (view) -> Bool in
            return view is UIImageView
        } as? UIImageView

        return view
    }
}
}

答案 1 :(得分:3)

Politta建议的代码无法在iOS 14上运行,因为Apple为UIPageControll引入了一些新的API。

请在此处查看详细信息UIPageControls New APIs

这是支持iOS 14的更新代码

class CustomPageControl: UIPageControl {

@IBInspectable var currentPageImage: UIImage?

@IBInspectable var otherPagesImage: UIImage?

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

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

override func awakeFromNib() {
    super.awakeFromNib()
    if #available(iOS 14.0, *) {
        defaultConfigurationForiOS14AndAbove()
    } else {
        pageIndicatorTintColor = .clear
        currentPageIndicatorTintColor = .clear
        clipsToBounds = false
    }
}

private func defaultConfigurationForiOS14AndAbove() {
    if #available(iOS 14.0, *) {
        for index in 0..<numberOfPages {
            let image = index == currentPage ? currentPageImage : otherPagesImage
            setIndicatorImage(image, forPage: index)
        }

        // give the same color as "otherPagesImage" color.
        pageIndicatorTintColor = .gray
        
        // give the same color as "currentPageImage" color.
        currentPageIndicatorTintColor = .red 
        /*
         Note: If Tint color set to default, Indicator image is not showing. So, give the same tint color based on your Custome Image.
        */
    }
}

private func updateDots() {
    if #available(iOS 14.0, *) {
        defaultConfigurationForiOS14AndAbove()
    } else {
        for (index, subview) in subviews.enumerated() {
            let imageView: UIImageView
            if let existingImageview = getImageView(forSubview: subview) {
                imageView = existingImageview
            } else {
                imageView = UIImageView(image: otherPagesImage)
                
                imageView.center = subview.center
                subview.addSubview(imageView)
                subview.clipsToBounds = false
            }
            imageView.image = currentPage == index ? currentPageImage : otherPagesImage
        }
    }
}

private func getImageView(forSubview view: UIView) -> UIImageView? {
    if let imageView = view as? UIImageView {
        return imageView
    } else {
        let view = view.subviews.first { (view) -> Bool in
            return view is UIImageView
        } as? UIImageView

        return view
    }
}
}

答案 2 :(得分:1)

这种方法适合我。我创建了一个自定义的pageControl类,并将点的图像更改为任何自定义图像。

在下面的代码中,我使用任何自定义图像更改了pageControl中第一个点的图像。

您可以根据需要更改 updateDots()方法。

希望它有所帮助!!!

override func viewDidLoad() {
    super.viewDidLoad()

    let pageControl = CustomPageControl(frame: CGRect(x: 100, y: 100, width: 104, height: 40))
    pageControl.numberOfPages = 5
    pageControl.currentPage = 0
    self.view.addSubview(pageControl)
}


class CustomPageControl: UIPageControl {


var imageToBeReplacedByDot: UIImage {
    return // Image you want to replace with dots
}
var circleImage: UIImage {

    return //Default Image
}


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

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

override func awakeFromNib() {
    super.awakeFromNib()
    self.pageIndicatorTintColor = UIColor.clear
    self.currentPageIndicatorTintColor = UIColor.clear
    self.clipsToBounds = false
}

func updateDots() {
    var i = 0
    for view in self.subviews {
        var imageView = self.imageView(forSubview: view)
        if imageView == nil {
            if i == 0 {
                imageView = UIImageView(image: imageToBeReplacedByDot)
            } else {
                imageView = UIImageView(image: circleImage)
            }
            imageView!.center = view.center
            view.addSubview(imageView!)
            view.clipsToBounds = false
        }
        if i == self.currentPage {
            imageView!.alpha = 1.0
        } else {
            imageView!.alpha = 0.5
        }
        i += 1
    }
}

fileprivate func imageView(forSubview view: UIView) -> UIImageView? {
    var dot: UIImageView?
    if let dotImageView = view as? UIImageView {
        dot = dotImageView
    } else {
        for foundView in view.subviews {
            if let imageView = foundView as? UIImageView {
                dot = imageView
                break
            }
        }
    }
    return dot
}
}

答案 3 :(得分:0)

支持我们的PageControl子类 iOS 14 ,只需执行以下操作即可:

    override var numberOfPages: Int {
        didSet {
            self._updateIndicators()
        }
    }
    
    override var currentPage: Int {
        didSet {
            self._updateIndicators()
        }
    }

    private func _updateIndicators() {
        var indicators: [UIView] = []
        
        if #available(iOS 14.0, *) {
            indicators = self.subviews.first?.subviews.first?.subviews ?? []
        } else {
            indicators = self.subviews
        }
        
        for (index, indicator) in indicators.enumerated() {
            let image = self.currentPage == index ? UIImage.init(named: "Page Indicator_Normal") : UIImage.init(named: "Page Indicator_Selected")
            if let dot = indicator as? UIImageView {
                dot.image = image
                
            } else {
                let imageView = UIImageView.init(image: image)
                indicator.addSubview(imageView)
                // here you can add some constraints to fix the imageview to his superview
            }
        }
    }