Ios 为UIPageControl中的点添加边框
我想为UIPageControl中的点添加边框颜色。下面是它的小图片: 我可以通过XCode配置第二个点,但我不能使第一个和第三个圆的内部为空。有没有一个简单的方法来实现这一点Ios 为UIPageControl中的点添加边框,ios,uipagecontrol,Ios,Uipagecontrol,我想为UIPageControl中的点添加边框颜色。下面是它的小图片: 我可以通过XCode配置第二个点,但我不能使第一个和第三个圆的内部为空。有没有一个简单的方法来实现这一点 谢谢:)编辑-Swift 3&4扩展以获得相同的结果- extension UIPageControl { func customPageControl(dotFillColor:UIColor, dotBorderColor:UIColor, dotBorderWidth:CGFloat) {
谢谢:)编辑-Swift 3&4扩展以获得相同的结果-
extension UIPageControl {
func customPageControl(dotFillColor:UIColor, dotBorderColor:UIColor, dotBorderWidth:CGFloat) {
for (pageIndex, dotView) in self.subviews.enumerated() {
if self.currentPage == pageIndex {
dotView.backgroundColor = dotFillColor
dotView.layer.cornerRadius = dotView.frame.size.height / 2
}else{
dotView.backgroundColor = .clear
dotView.layer.cornerRadius = dotView.frame.size.height / 2
dotView.layer.borderColor = dotBorderColor.cgColor
dotView.layer.borderWidth = dotBorderWidth
}
}
}
}
要使用它,请在viewDidLoad()或ViewDidAspect()中编写以下代码
在Objective-C中使用以下代码-
- (void) customPageControlWithFillColor:(UIColor*)dotFillColor borderColor:(UIColor*)dotBorderColor borderWidth:(CGFloat)dotBorderWidth {
for (int pageIndex = 0; pageIndex < _pageControl.numberOfPages; pageIndex++) {
UIView* dotView = [_pageControl.subviews objectAtIndex:pageIndex];
if (_pageControl.currentPage == pageIndex) {
dotView.backgroundColor = dotFillColor;
dotView.layer.cornerRadius = dotView.frame.size.height / 2;
} else {
dotView.backgroundColor = [UIColor clearColor];
dotView.layer.cornerRadius = dotView.frame.size.height / 2;
dotView.layer.borderColor = dotBorderColor.CGColor;
dotView.layer.borderWidth = dotBorderWidth;
}
}
}
-(void)customPageControlWithFillColor:(UIColor*)dotFillColor borderColor:(UIColor*)dotBorderColor borderWidth:(CGFloat)dotBorderWidth{
对于(int pageIndex=0;pageIndex<\u pageControl.numberOfPages;pageIndex++){
UIView*dotView=[\u pageControl.subviews objectAtIndex:pageIndex];
if(_pageControl.currentPage==pageIndex){
dotView.backgroundColor=dotFillColor;
dotView.layer.cornerRadius=dotView.frame.size.height/2;
}否则{
dotView.backgroundColor=[UIColor clearColor];
dotView.layer.cornerRadius=dotView.frame.size.height/2;
dotView.layer.borderColor=dotBorderColor.CGColor;
dotView.layer.borderWidth=dotBorderWidth;
}
}
}
输出-
当前属性可用于
UIPageControl
,这是不可能的。但是您可以通过集成任何模仿iOSUIPageControl
功能的页面控件来实现
另一个答案适用于修补程序。我非常不同意那个解决方案。我正在使用。这是一个用Objective-C编写的非常棒的框架,因此它能够与Swift 2和Swift 3配合使用 用法非常简单:
pod 'SMPageControl'
然后在页面视图控制器中
:
import SMPageControl
class MyController: UIPageViewController {
var pageControl = SMPageControl()
override func viewDidLoad() {
super.viewDidLoad()
stylePageControl()
}
private func stylePageControl() {
pageControl = SMPageControl(frame: CGRect(x: 0, y: self.view.frame.size.height - 50, width: self.view.frame.size.width, height: 50))
pageControl.numberOfPages = yourPageControllerArray.count
// the first (first) picture is the item in the bar, that is unused
// the second (currentFirst) is an item that we use, when this is the current active page
// in this example, we don't have dots, but we use "pictues" as dots
let first = UIImage(named: "pageHome")?.imageWithColor(UIColor.grayColor())
let currentFirst = first?.imageWithColor(UIColor.whiteColor())
pageControl.setImage(first, forPage: 0)
pageControl.setCurrentImage(currentFirst, forPage: 0)
let second = UIImage(named: "pageMusic")?.imageWithColor(UIColor.grayColor())
let currentSecond = second?.imageWithColor(UIColor.whiteColor())
pageControl.setImage(second, forPage: 1)
pageControl.setCurrentImage(currentSecond, forPage: 1)
pageControl.indicatorMargin = 30.0 // this is the space between the dots
self.view.addSubview(pageControl)
}
我使用过的UIImage扩展:
extension UIImage {
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()! as CGContextRef
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, CGBlendMode.Normal)
let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
CGContextClipToMask(context, rect, self.CGImage!)
CGContextFillRect(context, rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage
UIGraphicsEndImageContext()
return newImage
}
}
结果如下所示:
现在我们当然可以使用彩色点作为图像(空白颜色为未使用的颜色,填充颜色为使用的颜色),然后我们就可以得到要求的结果。来自@RiosK的SWIFT 3版本
func updatePageControl() {
for (index, dot) in pageControl.subviews.enumerated() {
if index == pageControl.currentPage {
dot.backgroundColor = dotColor
dot.layer.cornerRadius = dot.frame.size.height / 2;
} else {
dot.backgroundColor = UIColor.clear
dot.layer.cornerRadius = dot.frame.size.height / 2
dot.layer.borderColor = dotColor.cgColor
dot.layer.borderWidth = dotBorderWidth
}
}
}
另一种方法是使用正确大小的图案图像(目前直径为7点)。结果如下: 这是如何做到的:
let image = UIImage.outlinedEllipse(size: CGSize(width: 7.0, height: 7.0), color: .darkGray)
self.pageControl.pageIndicatorTintColor = UIColor.init(patternImage: image!)
self.pageControl.currentPageIndicatorTintColor = .darkGray
它对UIImage
使用了这个简单的小扩展:
/// An extension to `UIImage` for creating images with shapes.
extension UIImage {
/// Creates a circular outline image.
class func outlinedEllipse(size: CGSize, color: UIColor, lineWidth: CGFloat = 1.0) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
context.setStrokeColor(color.cgColor)
context.setLineWidth(lineWidth)
// Inset the rect to account for the fact that strokes are
// centred on the bounds of the shape.
let rect = CGRect(origin: .zero, size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5)
context.addEllipse(in: rect)
context.strokePath()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
这样做的缺点是,如果在操作系统更新中更改了点大小,图像将看起来很奇怪,因为它将被平铺或剪裁。需要在ViewDidDisplay中添加此选项
pageControl.customPageControl(dotFillColor: .orange, dotBorderColor: .green, dotBorderWidth: 2)
for (int i = 0; i < _pageControl.numberOfPages; i++) {
UIView* dot = [_pageControl.subviews objectAtIndex:i];
if (i == _pageControl.currentPage) {
dot.backgroundColor = [UIColor whiteColor];
dot.layer.cornerRadius = dot.frame.size.height / 2;
} else {
dot.backgroundColor = [UIColor clearColor];
dot.layer.cornerRadius = dot.frame.size.height / 2;
dot.layer.borderColor = [UIColor whiteColor].CGColor;
dot.layer.borderWidth = 1;
}
}
for(int i=0;i<\u pageControl.numberOfPages;i++){
UIView*dot=[\u pageControl.subviews objectAtIndex:i];
if(i==\u pageControl.currentPage){
dot.backgroundColor=[UIColor whiteColor];
dot.layer.cornerRadius=dot.frame.size.height/2;
}否则{
dot.backgroundColor=[UIColor clearColor];
dot.layer.cornerRadius=dot.frame.size.height/2;
dot.layer.borderColor=[UIColor whiteColor].CGColor;
dot.layer.borderWidth=1;
}
}
只需添加这两行,然后添加所需的图像
pageControl.currentPageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "slider_selected")!)
pageControl.pageIndicatorTintColor = UIColor.init(patternImage: UIImage(named: "slider")!)
Swift 4。您可以指定borderColor,然后观察currentPage属性以更改点的边框:
class CustomPageControl: UIPageControl {
var borderColor: UIColor = .clear
override var currentPage: Int {
didSet {
updateBorderColor()
}
}
func updateBorderColor() {
subviews.enumerated().forEach { index, subview in
if index != currentPage {
subview.layer.borderColor = borderColor.cgColor
subview.layer.borderWidth = 1
} else {
subview.layer.borderWidth = 0
}
}
}
}
Swift 5版本
func customPageControl(dotFillColor: UIColor, dotBorderColor: UIColor, dotBorderWidth: CGFloat) {
for (pageIndex, dotView) in self.subviews.enumerated() {
dotView.backgroundColor = currentPage == pageIndex ? dotFillColor : .clear
dotView.layer.cornerRadius = dotView.frame.size.height / 2
dotView.layer.borderColor = dotBorderColor.cgColor
dotView.layer.borderWidth = dotBorderWidth
}
}
卢克·罗杰斯的解决方案,用objective-c写成:
-(UIImage *) outlinedEllipse:(CGSize)size color: (UIColor*) lineColor width:(CGFloat) lineWidth {
UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
if (context == NULL) {
return NULL;
}
CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
CGContextSetLineWidth(context, lineWidth);
// Inset the rect to account for the fact that strokes are
// centred on the bounds of the shape.
CGRect rect = CGRectInset(CGRectMake(0, 0, 7.0f, 7.0f), lineWidth * 0.5, lineWidth * 0.5);
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
现代卢克·罗杰斯(埃尔克·克罗纳说它不够现代,不适合ios14)
有其他方法可以实现这一点吗?@EmrahAkgül如果您在storyboard中设置页面控件,请尝试在
viewdide出现后调用for
循环。这对我有用。当我在viewDidLoad
中调用循环时,它不起作用。谢谢@rioskborderColor
和borderWidth
设置就足够了。其余的不用了<可以使用pageIndicatorTintColor
和currentPageIndicatorTintColor
设置状态的代码>背景颜色。投票支持这一点,因为它有帮助。请确保在视图出现后调用,如上面提到的@Therohansap@i在我的案例中显示它。请参阅附件。如果操作系统更新更改了视图层次结构,则在子视图上进行迭代可能随时中断。“其他答案已应用修补程序。”还有什么解决方案我必须在视图中添加call nice函数才能使其工作。在ios 14中不工作在ios 14中不工作
extension UIImage
{
// https://stackoverflow.com/questions/35842040/add-border-for-dots-in-uipagecontrol
// modernized Luke Rogers
class func outlinedEllipse(size: CGSize, color: UIColor, lineWidth: CGFloat = 1.0) -> UIImage? {
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { context in
color.setFill()
context.cgContext.setLineWidth(lineWidth)
// Inset the rect to account for the fact that strokes are
// centred on the bounds of the shape.
let rect = CGRect(origin: .zero, size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5)
context.cgContext.strokeEllipse(in: rect)
}
return image
}
}