ios 在 UIPageControl 的索引 0 处自定义带有 UIPageControl 图像的点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12190147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:56:31  来源:igfitidea点击:

Customize dot with image of UIPageControl at index 0 of UIPageControl

iphoneios

提问by Sovannarith

I'm a new learner of ios programming. I have tried to search with another example and more questions at stackoverflow but it's not my goal. I want to set an image of dot at index 0 of UIPageControl as similar as iPhone search homescreen. Have any way to do it ? Please explain me with some code or another useful link.

我是ios编程的新手。我试图在 stackoverflow 上搜索另​​一个示例和更多问题,但这不是我的目标。我想在 UIPageControl 的索引 0 处设置一个点图像,类似于 iPhone 搜索主屏幕。有什么办法吗?请用一些代码或其他有用的链接向我解释。

Thanks in advance

提前致谢

enter image description here

在此处输入图片说明

采纳答案by Gypsa

Try this link:-

试试这个链接:-

Answer with GrayPageControl:- Is there a way to change page indicator dots color

用 GrayPageControl 回答:- 有没有办法改变页面指示器点的颜色

It is really good and reliable.I also have used this code.

真的很好很可靠。我也用过这个代码。

You might have to do some more customization as

您可能需要做一些更多的自定义

-(void) updateDots
{
    for (int i = 0; i < [self.subviews count]; i++)
    {
        UIImageView* dot = [self.subviews objectAtIndex:i];

        if (i == self.currentPage) {
            if(i==0) {
                dot.image = [UIImage imageNamed:@"activesearch.png"];
            } else {
                dot.image = activeImage;
            }        
        } else {
            if(i==0) {
                dot.image = [UIImage imageNamed:@"inactivesearch.png"];
            } else {
                dot.image = inactiveImage;
            }
        }
    }
}

回答by Sahil Mahajan

I have found a solution for this problem. I know it is not the way but it will work till iOS 8 will be launched in the market.

我已经找到了解决这个问题的方法。我知道这不是办法,但它会一直工作到 iOS 8 将在市场上推出。

Reason for Crash:

崩溃原因:

in iOS 7 [self.subViews objectAtIndex: i] returns UIView Instead of UIImageView and setImage is not the property of UIView and the app crashes. I solve my problem using this following code.

在 iOS 7 中 [self.subViews objectAtIndex: i] 返回 UIView 而不是 UIImageView 并且 setImage 不是 UIView 的属性并且应用程序崩溃。我使用以下代码解决了我的问题。

Check Whether the subview is UIView(for iOS7) or UIImageView(for iOS6 or earlier). And If it is UIView I am going to add UIImageView as subview on that view and voila its working and not crash..!!

检查子视图是 UIView(适用于 iOS7)还是 UIImageView(适用于 iOS6 或更早版本)。如果它是 UIView,我将添加 UIImageView 作为该视图的子视图,瞧它的工作,而不是崩溃..!!

-(void) updateDots
{
    for (int i = 0; i < [self.subviews count]; i++)
    {
        UIImageView * dot = [self imageViewForSubview:  [self.subviews objectAtIndex: i]];
        if (i == self.currentPage) dot.image = activeImage;
        else dot.image = inactiveImage;
    }
}
- (UIImageView *) imageViewForSubview: (UIView *) view
{
    UIImageView * dot = nil;
    if ([view isKindOfClass: [UIView class]])
    {
        for (UIView* subview in view.subviews)
        {
            if ([subview isKindOfClass:[UIImageView class]])
            {
                dot = (UIImageView *)subview;
                break;
            }
        }
        if (dot == nil)
        {
            dot = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, view.frame.size.width, view.frame.size.height)];
            [view addSubview:dot];
        }
    }
    else
    {
        dot = (UIImageView *) view;
    }

    return dot;
}

Also, to clear the images that are already there, set the tint colors for the existing indicators to transparent:

此外,要清除已经存在的图像,请将现有指标的色调颜色设置为透明:

- (void)awakeFromNib
{   
    self.pageIndicatorTintColor = [UIColor clearColor];
    self.currentPageIndicatorTintColor = [UIColor clearColor];
}

Hope this will solve ur issue for iOS 7.

希望这将解决您的 iOS 7 问题。

Happy coding

快乐编码

回答by Kiran Patil

Simply change the UIPageControl page indicator Color with pattern Image self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"circle"]];

只需使用图案图像更改 UIPageControl 页面指示器颜色 self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"circle"]];

回答by Dmitry

The best compilation of the code for Swift 3 to replace the first iconof UIPageControlby a location marker:

用位置标记替换第一个图标的Swift 3 代码的最佳编译UIPageControl

import UIKit

class LocationPageControl: UIPageControl {

    let locationArrow: UIImage = UIImage(named: "locationArrow")!
    let pageCircle: UIImage = UIImage(named: "pageCircle")!

    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: locationArrow)
                } else {
                    imageView = UIImageView(image: pageCircle)
                }
                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
    }
}

Attached images:

附上图片:

enter image description hereenter image description here

在此处输入图片说明在此处输入图片说明

回答by Fonix

I've created a custom page controller that should function in mostly the same way without hacking into the internals of a UIPageControl or having a whole library for one small widget.

我已经创建了一个自定义页面控制器,它应该以几乎相同的方式运行,而无需侵入 UIPageControl 的内部结构或为一个小部件拥有一个完整的库。

Just place an empty UIStackView in your storyboard and make its custom class this class below, and use numberOfPagesand currentPagejust like a normal UIPageControl. Set the spacing on the UIStackView to change how much space there is between the views.

只需在您的故事板中放置一个空的 UIStackView 并将其自定义类设置为下面的这个类,并像普通的 UIPageControl 一样使用numberOfPages和使用currentPage。在 UIStackView 上设置间距以更改视图之间有多少空间。

Swift 4.2

斯威夫特 4.2

/**
 If adding via storyboard, you should not need to set a width and height constraint for this view,
 just set a placeholder for each so autolayout doesnt complain and this view will size itself once its populated with pages at runtime
 */
class PageControl: UIStackView {

    @IBInspectable var currentPageImage: UIImage = UIImage(named: "whiteCircleFilled")!
    @IBInspectable var pageImage: UIImage = UIImage(named: "whiteCircleOutlined")!
    /**
     Sets how many page indicators will show
     */
    var numberOfPages = 3 {
        didSet {
            layoutIndicators()
        }
    }
    /**
     Sets which page indicator will be highlighted with the **currentPageImage**
     */
    var currentPage = 0 {
        didSet {
            setCurrentPageIndicator()
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        axis = .horizontal
        distribution = .equalSpacing
        alignment = .center

        layoutIndicators()
    }

    private func layoutIndicators() {

        for i in 0..<numberOfPages {

            let imageView: UIImageView

            if i < arrangedSubviews.count {
                imageView = arrangedSubviews[i] as! UIImageView // reuse subview if possible
            } else {
                imageView = UIImageView()
                addArrangedSubview(imageView)
            }

            if i == currentPage {
                imageView.image = currentPageImage
            } else {
                imageView.image = pageImage
            }
        }

        // remove excess subviews if any
        let subviewCount = arrangedSubviews.count
        if numberOfPages < subviewCount {
            for _ in numberOfPages..<subviewCount {
                arrangedSubviews.last?.removeFromSuperview()
            }
        }
    }

    private func setCurrentPageIndicator() {

        for i in 0..<arrangedSubviews.count {

            let imageView = arrangedSubviews[i] as! UIImageView

            if i == currentPage {
                imageView.image = currentPageImage
            } else {
                imageView.image = pageImage
            }
        }
    }
}

Works for my purposes but I make no guarantees

适用于我的目的,但我不做任何保证

回答by CodenameDuchess

Update for Swift 3.0 ... you know if you are OK with accepting stated risk: "Modifying the subviews of an existing control is fragile".

Swift 3.0 的更新......你知道你是否同意接受声明的风险:“修改现有控件的子视图是脆弱的”。

 import UIKit

 class CustomImagePageControl: UIPageControl {

   let activeImage:UIImage = UIImage(named: "SelectedPage")!
   let inactiveImage:UIImage = UIImage(named: "UnselectedPage")!

   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 {
             if let imageView = self.imageForSubview(view) {
                 if i == self.currentPage {
                     imageView.image = self.activeImage
                 } else {
                     imageView.image = self.inactiveImage
                 }
                 i = i + 1
             } else {
                 var dotImage = self.inactiveImage
                 if i == self.currentPage {
                     dotImage = self.activeImage
                 }
                 view.clipsToBounds = false
                 view.addSubview(UIImageView(image:dotImage))
                 i = i + 1
             }
         }
     }

     fileprivate func imageForSubview(_ 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
     }
 }

回答by Jonas

You just need do it like this:

你只需要这样做:

((UIImageView *)[[yourPageControl subviews] objectAtIndex:0]).image=[UIImage imageNamed:@"search.png"];

回答by BornCoder

I think for this you need to customize whole UIPageControl. Please find more out at below links

我认为为此您需要自定义整个UIPageControl. 请在以下链接中了解更多信息

  1. How can i change the color of pagination dots of UIPageControl?

  2. http://iphoneappcode.blogspot.in/2012/03/custom-uipagecontrol.html

  1. 如何更改 UIPageControl 的分页点的颜色?

  2. http://iphoneappcode.blogspot.in/2012/03/custom-uipagecontrol.html

回答by saranpol

From iProgrammer's answer
In case you want to hide the original dot

来自 iProgrammer 的回答
如果您想隐藏原始点

- (UIImageView *)imageViewForSubview:(UIView *)view {
    UIImageView * dot = nil;
    [view setBackgroundColor:[UIColor clearColor]]; << add this line

回答by Vello Vaherpuu

Following the previous answers I came up with the solution below. Keep in mind that I had to add valueChanged listener that calls updateDots() as well in controller to handle taps made on UIPageControl

按照前面的答案,我想出了下面的解决方案。请记住,我必须在控制器中添加调用 updateDots() 的 valueChanged 侦听器来处理在 UIPageControl 上进行的点击

import UIKit

class PageControl: UIPageControl {
    private struct Constants {
        static let activeColor: UIColor = .white
        static let inactiveColor: UIColor = .black
        static let locationImage: UIImage = UIImage(named: "Location")!
    }

    // Update dots when currentPage changes
    override var currentPage: Int {
        didSet {
            updateDots()
        }
    }

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

    func updateDots() {
        for (index, view) in self.subviews.enumerated() {
            // Layers will be redrawn, remove old.
            view.layer.sublayers?.removeAll()
            if index == 0 {
                drawImage(view: view)
            } else {
                drawDot(index: index, view: view)
            }
        }
    }

    private func drawDot(index: Int, view: UIView) {
        let dotLayer = CAShapeLayer()
        dotLayer.path = UIBezierPath(ovalIn: view.bounds).cgPath
        dotLayer.fillColor = getColor(index: index)

        view.layer.addSublayer(dotLayer)
    }

    private func drawImage(view: UIView) {
        let height = view.bounds.height * 2
        let width = view.bounds.width * 2
        let topMargin: CGFloat = -3.5

        let maskLayer = CALayer()
        maskLayer.frame = CGRect(x: 0, y: 0, width: width, height: height)
        maskLayer.contents = Constants.locationImage.cgImage
        maskLayer.contentsGravity = .resizeAspect

        let imageLayer = CALayer()
        imageLayer.frame = CGRect(x:0, y: topMargin, width: width, height: height)
        imageLayer.mask = maskLayer
        imageLayer.backgroundColor = getColor()

        view.backgroundColor = .clear // Otherwise black background
        view.layer.addSublayer(imageLayer)
    }

    private func getColor(index: Int? = 0) -> CGColor {
        return currentPage == index ? Constants.activeColor.cgColor : Constants.inactiveColor.cgColor
    }
}