web-dev-qa-db-fra.com

Ajouter une bordure pour les points dans UIPageControl

Je souhaite ajouter une couleur de bordure pour les points dans UIPageControl. Voici la petite image de celle-ci:

 enter image description here

Je peux mettre le deuxième point en le configurant à partir de XCode mais je ne peux pas vider les premier et troisième cercles. Y a-t-il un moyen simple d'y parvenir?

Merci :)

13
Emrah Akgül

Cela n’est pas possible avec les propriétés actuelles disponibles pour UIPageControl. Mais vous pouvez le faire en intégrant n'importe quel tiers contrôle de page qui imite la fonctionnalité de iOS UIPageControl.

Autre réponse a appliqué un patch. Je suis très en désaccord avec cette solution.

6
Hemang

Edited- Swift 3 & 4 extension pour obtenir le même résultat-

extension UIPageControl {

    func customPageControl(dotFillColor:UIColor, dotBorderColor:UIColor, dotBorderWidth:CGFloat) {
        for (pageIndex, dotView) in self.subviews.enumerated() {
            if self.currentPage == pageIndex {
                dotView.backgroundColor = dotFillColor
                dotView.layer.cornerRadius = dotView.frame.size.height / 2
            }else{
                dotView.backgroundColor = .clear
                dotView.layer.cornerRadius = dotView.frame.size.height / 2
                dotView.layer.borderColor = dotBorderColor.cgColor
                dotView.layer.borderWidth = dotBorderWidth
            }
        }
    }

}

pour l'utiliser, écrivez en dessous du code dans viewDidLoad () ou viewDidAppear ()

pageControl.customPageControl(dotFillColor: .orange, dotBorderColor: .green, dotBorderWidth: 2)

Dans Objective-C, utilisez ci-dessous le code-

- (void) customPageControlWithFillColor:(UIColor*)dotFillColor borderColor:(UIColor*)dotBorderColor borderWidth:(CGFloat)dotBorderWidth {
    for (int pageIndex = 0; pageIndex < _pageControl.numberOfPages; pageIndex++) {
        UIView* dotView = [_pageControl.subviews objectAtIndex:pageIndex];
        if (_pageControl.currentPage == pageIndex) {
            dotView.backgroundColor = dotFillColor;
            dotView.layer.cornerRadius = dotView.frame.size.height / 2;
        } else {
            dotView.backgroundColor = [UIColor clearColor];
            dotView.layer.cornerRadius = dotView.frame.size.height / 2;
            dotView.layer.borderColor = dotBorderColor.CGColor;
            dotView.layer.borderWidth = dotBorderWidth;
        }
    }
}

Sortie-

 enter image description here

19
rohitk-iOSDev

Une autre approche consisterait à utiliser une image de motif de la taille correcte (qui a actuellement 7 points de diamètre). Voici à quoi ressemble le résultat:

 Pagination dots screenshot

Et voici comment c'est fait:

let image = UIImage.outlinedEllipse(size: CGSize(width: 7.0, height: 7.0), color: .darkGray)
self.pageControl.pageIndicatorTintColor = UIColor.init(patternImage: image!)
self.pageControl.currentPageIndicatorTintColor = .darkGray

Qui utilise cette simple petite extension à UIImage:

/// An extension to `UIImage` for creating images with shapes.
extension UIImage {

    /// Creates a circular outline image.
    class func outlinedEllipse(size: CGSize, color: UIColor, lineWidth: CGFloat = 1.0) -> UIImage? {

        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        guard let context = UIGraphicsGetCurrentContext() else {
                return nil
        }

        context.setStrokeColor(color.cgColor)
        context.setLineWidth(lineWidth)
        // Inset the rect to account for the fact that strokes are
        // centred on the bounds of the shape.
        let rect = CGRect(Origin: .zero, size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5)
        context.addEllipse(in: rect)
        context.strokePath()

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

L'inconvénient est que si la taille du point change dans une mise à jour du système d'exploitation, l'image aura un aspect bizarre, car elle sera mosaïque ou coupée.

16
Luke Rogers

Swift 3 Version de @RiosK

func updatePageControl() {
    for (index, dot) in pageControl.subviews.enumerated() {
        if index == pageControl.currentPage {
            dot.backgroundColor = dotColor
            dot.layer.cornerRadius = dot.frame.size.height / 2;
        } else {
            dot.backgroundColor = UIColor.clear
            dot.layer.cornerRadius = dot.frame.size.height / 2
            dot.layer.borderColor = dotColor.cgColor
            dot.layer.borderWidth = dotBorderWidth
        }
    }
}
14
Jerome

J'utilise SMPageControl . C'est un framework vraiment génial écrit en Objective-C, il est donc capable de fonctionner avec Swift 2 et Swift 3.

 enter image description here

L'utilisation est complètement simple:

pod 'SMPageControl'

Puis dans votre PageViewController:

import SMPageControl

class MyController: UIPageViewController {

     var pageControl = SMPageControl()

     override func viewDidLoad() {
        super.viewDidLoad()

        stylePageControl()
    }

private func stylePageControl() {

    pageControl = SMPageControl(frame: CGRect(x: 0, y: self.view.frame.size.height - 50, width: self.view.frame.size.width, height: 50))
    pageControl.numberOfPages = yourPageControllerArray.count

//  the first (first) picture is the item in the bar, that is unused
//  the second (currentFirst) is an item that we use, when this is the current active page
//  in this example, we don't have dots, but we use "pictues" as dots

    let first = UIImage(named: "pageHome")?.imageWithColor(UIColor.grayColor())
    let currentFirst = first?.imageWithColor(UIColor.whiteColor())

    pageControl.setImage(first, forPage: 0)
    pageControl.setCurrentImage(currentFirst, forPage: 0)

    let second = UIImage(named: "pageMusic")?.imageWithColor(UIColor.grayColor())
    let currentSecond = second?.imageWithColor(UIColor.whiteColor())

    pageControl.setImage(second, forPage: 1)
    pageControl.setCurrentImage(currentSecond, forPage: 1)

    pageControl.indicatorMargin = 30.0 // this is the space between the dots

    self.view.addSubview(pageControl)
}

UIImage Extension j'ai utilisé:

extension UIImage {

    func imageWithColor(color1: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        color1.setFill()

        let context = UIGraphicsGetCurrentContext()! as CGContextRef
        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetBlendMode(context, CGBlendMode.Normal)

        let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
        CGContextClipToMask(context, rect, self.CGImage!)
        CGContextFillRect(context, rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
        UIGraphicsEndImageContext()

        return newImage
    }

}

Le résultat ressemble à ceci:

 enter image description here

Maintenant, nous pourrions bien sûr utiliser des points colorés comme images (vierges colorées comme non utilisées et colorées comme utilisées), nous aurions alors le résultat demandé.

2
David Seek

Ajoutez simplement ces deux lignes et ajoutez l'image désirée !!

pageControl.currentPageIndicatorTintColor  = UIColor.init(patternImage: UIImage(named: "slider_selected")!)

pageControl.pageIndicatorTintColor =  UIColor.init(patternImage: UIImage(named: "slider")!)
1
Arnab Ghoshal

Besoin d'ajouter ceci dans viewDidAppear

 for (int i = 0; i < _pageControl.numberOfPages; i++) {
        UIView* dot = [_pageControl.subviews objectAtIndex:i];
        if (i == _pageControl.currentPage) {
            dot.backgroundColor = [UIColor whiteColor];
            dot.layer.cornerRadius = dot.frame.size.height / 2;
        } else {
            dot.backgroundColor = [UIColor clearColor];
            dot.layer.cornerRadius = dot.frame.size.height / 2;
            dot.layer.borderColor = [UIColor whiteColor].CGColor;
            dot.layer.borderWidth = 1;
        }
    }
0
Alex_Burla