Custom UIPageControl with dot images
当我需要自定义UIPageControl时,我使用了此解决方案。
为新版本的swift稍加修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | class myPageControl: UIPageControl { var activeImage: UIImage! var inactiveImage: UIImage! required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) activeImage = UIImage(named:"active.png")! inactiveImage = UIImage(named:"inactive.png")! } func updateDots() { for i in 0 ..< self.subviews.count { let dot : UIImageView = imageViewForSubview(self.subviews[i]) if (i == self.currentPage) { dot.image = activeImage } else { dot.image = inactiveImage } } } func imageViewForSubview(view: UIView) -> UIImageView { var dot: UIImageView? = nil if (view.isKindOfClass(UIView)) { for subview: UIView in view.subviews { if (subview is UIImageView) { dot = (subview as! UIImageView) } } if dot == nil { dot = UIImageView(frame: CGRectMake(0.0, 0.0, view.frame.size.width, view.frame.size.height)) view.addSubview(dot!) } } else { dot = (view as! UIImageView) } return dot! } func setPage(page: Int) { super.currentPage = page self.updateDots() } } |
我的问题是,当您第一次启动应用程序时,我无法更改图片。
仅在更改页面时才会更改。
在
Swift 3.0 ...您是否可以接受声明的风险:"修改现有控件的子视图很脆弱"。
您将必须在viewDidAppear()中调用" updateDots()",并为页面控件调用valueChanged处理程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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 } } |
我对@CodenameDuchess的答案做了一些改进。您也可以在xibs / storyboards上自定义图像。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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 2 3 4 | func scrollViewDidScroll(_ scrollView: UIScrollView) { let index = Int(scrollView.contentOffset.x / scrollView.frame.width) aStackView.insertArrangedSubview(activeImageView, at: index) } |
ps。 UIStackView的
Apple为UIPageControll引入了一些新的API。从iOS 14开始,有一个提供自定义图像的选项。
这是支持iOS 14的更新代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 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 } } } |