当我需要自定义我的UIPageControl时,我使用了this和this解决方案。
稍微修改它以获得新版本的swift:
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()
}
}
我的问题是,当您第一次启动应用时,我无法更改图片。 它仅在页面更改时更改。
在viewDidLoad()
中,我添加了setPage(0)
和updateDots()
,但没有结果。我能做错什么?
答案 0 :(得分:9)
Swift 3.0 ...你知道你是否接受陈述的风险:&#34;修改现有控件的子视图是脆弱的&#34;。
您必须致电&#34; updateDots()&#34;在viewDidAppear()和页面控件的valueChanged处理程序。
{{1}}
答案 1 :(得分:4)
我改进了@CodenameDuchess的答案。您还可以在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
}
}
}
答案 2 :(得分:1)
您可以使用UIStackView
来达到您想要的效果。
将activeImageView
和其他inactiveImageView
放入aStackView
。而不仅仅是更改activeImageView
中的scrollViewDidScroll(_:)
索引。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let index = Int(scrollView.contentOffset.x / scrollView.frame.width)
aStackView.insertArrangedSubview(activeImageView, at: index)
}
PS。 UIStackView的insertArrangedSubview(_:at:)
只是更新了排列的子视图的堆栈索引(如果它已经在arrangeSubviews列表中)。
答案 3 :(得分:1)
Apple已经为UIPageControll引入了一些新的API。从iOS 14开始,可以选择提供自定义图片。
这是支持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
}
}
}