自定义 PageControl 图像 - Swift
Posted
技术标签:
【中文标题】自定义 PageControl 图像 - Swift【英文标题】:Custom PageControl image - Swift 【发布时间】:2017-11-14 06:36:20 【问题描述】:我正在尝试为 UIPageControl 点设置图像。
我需要更改默认点,而不是我需要图像。 我使用了下面的代码
self.pageCtrl.currentPageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "Page Indicator_Selected")!)
self.pageCtrl.pageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "Page Indicator_Normal")!)
我可以在 Pagecontrol 中设置图像,但是它与默认点重叠。
【问题讨论】:
Custom UIPageControl with dot images的可能重复 【参考方案1】: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
【讨论】:
这个工作但颜色效果不能正常工作 尝试使用具有透明背景的图像并获得正确的 RGB 或十六进制。这可能会有所帮助。 我试过了,它在第一次加载和滚动后会给出不同的颜色。 您的布局似乎没有正确更新。尝试使用 layoutIfNeeded() 或延迟。 它的更新问题是它第一次显示相反的色调【参考方案2】:我改进了史密斯特工的答案,可以处理任意数量的页面。您可以自定义 xibs/storyboards 上的图像。
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
【讨论】:
这个不适用于iOS14,子视图数总是1【参考方案3】:这种方法对我有用。我创建了一个自定义 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
【讨论】:
【参考方案4】:支持 iOS 14,我们的 PageControl 子类,我们可以这样做:
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
【讨论】:
以上是关于自定义 PageControl 图像 - Swift的主要内容,如果未能解决你的问题,请参考以下文章
带有 PageControl 的 ScrollView 中的图像
delphi中如何让pagecontrol的tab宽度自适应
缩放后 UIImageView 在 PageControl 的右侧被切断