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
Customize dot with image of UIPageControl at index 0 of UIPageControl
提问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
提前致谢
采纳答案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 UIPageControl
by 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:
附上图片:
回答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 numberOfPages
and currentPage
just 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
. 请在以下链接中了解更多信息
回答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
}
}