My code worked fine from iOS 7 to 8. With the update yesterday the custom images on my pins were replaced by the standard pin image.
Any suggestions?
My code:
extension ViewController: MKMapViewDelegate {
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView! {
if annotation is MKUserLocation {
return nil
}
let reuseId = String(stringInterpolationSegment: annotation.coordinate.longitude)
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.image = getRightImage(annotation.title!!)
}
let button = UIButton(type: UIButtonType.DetailDisclosure)
pinView?.rightCalloutAccessoryView = button
return pinView
}
}
The function to get the image returns a UIImage based on the name:
func getRightImage (shopName:String)-> UIImage{
var correctImage = UIImage()
switch shopName
{
case "Kaisers":
correctImage = UIImage(named: "Kaisers.jpg")!
default:
correctImage = UIImage(named: "sopiconsmall.png")!
}
return correctImage
}
No the map looks like this:
Instead of creating an MKPinAnnotationView, create a plain MKAnnotationView.
The MKPinAnnotationView subclass tends to ignore the image property since it's designed to show the standard red, green, purple pins only (via the pinColor property).
When you switch to MKAnnotationView, you'll have to comment out the animatesDrop line as well since that property is specific to MKPinAnnotationView.
Following code works perfectly on all iOS 6 to iOS 9 devices:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// create a proper annotation view, be lazy and don't use the reuse identifier
MKAnnotationView *view = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"identifier"];
// create a disclosure button for map kit
UIButton *disclosure = [UIButton buttonWithType:UIButtonTypeContactAdd];
[disclosure addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(disclosureTapped)]];
view.rightCalloutAccessoryView = disclosure;
view.enabled = YES;
view.image = [UIImage imageNamed:#"map_pin"];
return view;
}
For Swift 4
func mapView(mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = String(stringInterpolationSegment: annotation.coordinate.longitude)
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinView == nil {
pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.image = getRightImage(annotation.title!!)
}
let button = UIButton(type: UIButtonType.DetailDisclosure)
pinView?.rightCalloutAccessoryView = button
return pinView
}
in Obj-c i made a switch statement which i used to move around in my app for iPad using UIsplitviewcontroller
now i want to do the same in swift... i tried for a couple of hours and now the only thing i haven't been able to try is the code because it says some sort of compile error
anyway
here's what i got in Obj-c
-(void)initialSite:(int)viewId {
UIViewController *viewController;
switch (viewId) {
case 0:{
viewController = self.initital;
NSString *star = [NSString stringWithFormat:#"Velkommen til %#'s Bog",[data valueForKey:#"navn"]];
self.navigationItem.title = star;}
break;
case 1:{
viewController = self.startSide;
NSString *start = [NSString stringWithFormat:#"%#'s Bog, start-side",[data valueForKey:#"navn"]];
self.navigationItem.title = start;}
break;
}
[self showChildViewController:viewController];
}
and here's what i come up with so far in swift. still new to this and to understand it is a little hard even tho i have the swift programming language book
here's what i got so far in swift
let viewController = UIViewController()
switch viewController {
case "initial":
let initial : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc0 : UIViewController = initial.instantiateViewControllerWithIdentifier("initial") as UIViewController
self.presentViewController(vc0, animated: true, completion: nil)
let rowData: NSDictionary = self.menuItemArray[indexPath.row] as NSDictionary!
self.navigation.title = rowData["navn"] as? String
case "startSide":
let startSide : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc1 : UIViewController = startSide.instantiateViewControllerWithIdentifier("startSide") as UIViewController
let rowData: NSDictionary = self.manuItemArray[indexPath.row] as NSDictionary!
self.presentViewController(vc1, animated: true, completion: nil)
self.navigation.title = rowData["navn"] as? String
default:
}
the error is : Expected declaration at the line with
let viewController = UIViewcontroller()
Let's start with your Obj-C implementation:
-(void)initialSite:(int)viewId
{
UIViewController *viewController;
switch (viewId)
{
case 0:
{
viewController = self.initital;
NSString *star = [NSString stringWithFormat:#"Velkommen til %#'s Bog",[data valueForKey:#"navn"]];
self.navigationItem.title = star;
}
break;
case 1:
{
viewController = self.startSide;
NSString *start = [NSString stringWithFormat:#"%#'s Bog, start-side",[data valueForKey:#"navn"]];
self.navigationItem.title = start;
}
break;
}
[self showChildViewController:viewController];
}
Now this same snippet in Swift:
func initialSite(viewID:Int)
{
var viewController : UIViewController?
switch (viewID)
{
case 0:
viewController = self.initial
let navn = self.data["navn"] as? String
let star = "Velkommen til \(navn)'s Bog"
self.navigationItem.title = star
case 1:
viewController = self.startSide
let navn = self.data["navn"] as? String
let star = "\(navn)'s Bog, start-side"
self.navigationItem.title = star
default:
viewController = nil
// do nothing
}
self.showChildViewController(viewController)
}
The main thing you have to remember is the difference with var vs let. Typically you will use let to create things unless those things will have their value changed later, which you use var.
The other thing is the use of optionals, with the ? suffix. This is when the value may be nil (unset), otherwise it must contain a value.
Looks like SiLo beat me to it. Anyway I have my solution so I will post it. This is how I would do it:
func initialSite(viewId: Int) -> () {
var viewController: UIViewController?
let dataValue = data["navn"];
var start: String?
switch viewId {
case 1:
viewController = self.initital
start = "Velkommen til \(dataValue)'s Bog"
case 2:
viewController = self.startSide
start = "\(dataValue)'s Bog, start-side"
default:
break;
}
self.navigationItem.title = start!
showChildViewController(viewController!)
}
I want to have UITextField with multiple lines, after a quick google on this issue I found that I should use TextView so I did switch my code to use UITextView when I want multiple lines. My View still have other one line textField that I want to keep.
To make my TextView looks like TextField, I had to add code to set border and radius, but they look a little bit different on iOS7. Does anyone know:
what is the color for the UITextField border? when both enabled and disabled so I can sent my textview to match it.
what is radius of the corner of TextField.
what is the background color for UITextField when it is disabled[attached picture shows the text field has lighter shade of grey when it is disabled]? so i can set my text view to the same color when i disable user interaction.
If there is away to keep using textfield for multiline text, I am all ears and i switch to use it.
Best Regards,
I use this:
textView.layer.borderColor = [[UIColor colorWithRed:215.0 / 255.0 green:215.0 / 255.0 blue:215.0 / 255.0 alpha:1] CGColor];
textView.layer.borderWidth = 0.6f;
textView.layer.cornerRadius = 6.0f;
little differences in the params make it looks more like UITextField(I hope).
I use this:
#import <QuartzCore/QuartzCore.h>
-(void) textViewLikeTextField:(UITextView*)textView
{
[textView.layer setBorderColor:[[UIColor colorWithRed:212.0/255.0
green:212.0/255.0
blue:212.0/255.0
alpha:1] CGColor]];
[textView.layer setBorderWidth:1.0f];
[textView.layer setCornerRadius:7.0f];
[textView.layer setMasksToBounds:YES];
}
and get a good resut.
I have a small subclass of UITextView that gives in iOS 7 the same look as the UITextField
The interface is empty:
#interface MyTextView : UITextView
#end
The implementation overwrites the initialization and the setter of the 'editable' property:
#implementation MyTextView
//================================================================================
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame:frame];
if (self)
{
[self commonInit];
}
return self;
}
//================================================================================
- (id) initWithCoder: (NSCoder *) aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self commonInit];
}
return self;
}
//================================================================================
- (void) commonInit
{
self.layer.borderWidth = 1.0f;
self.layer.borderColor = [[UIColor colorWithRed:232.0/255.0
green:232.0/255.0 blue:232.0/255.0 alpha:1] CGColor];
self.layer.cornerRadius = 6;
}
//================================================================================
- (void) setEditable: (BOOL) editable
{
[super setEditable:editable];
if (editable)
{
self.backgroundColor = [UIColor whiteColor];
}
else
{
self.backgroundColor = [UIColor colorWithRed:250.0/255.0
green:250.0/255.0 blue:250.0/255.0 alpha:1];
}
}
//================================================================================
#end
This is the closest I got with enabled UITextView
[yourTextView.layer setBorderColor:[[[UIColor lightGrayColor] colorWithAlphaComponent:0.2] CGColor]];
[yourTextView.layer setBorderWidth:2.0];
yourTextView.layer.cornerRadius = 5;
yourTextView.clipsToBounds = YES;
yourTextView.textColor = [UIColor lightGrayColor];
Can someone give me an example of how to use SKLabelHorizontalAlignmentMode?
Here's how I'm defining my label:
RunningLevelLabel = [SKLabelNode labelNodeWithFontNamed:#"Chalkduster" ];
RunningLevelLabel.text = [NSString stringWithFormat:#"%i",numberOfBonusAlienPoints];
RunningLevelLabel.fontSize = 36;
RunningLevelLabel.position = CGPointMake(-10,-50); // offscreen
RunningLevelLabel.fontColor = [SKColor grayColor];
[StartScreenWindow addChild:RunningLevelLabel];
thanks,
rich
First create a label:
SKLabelNode *scoreLabel = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
scoreLabel.text = #"00000";
scoreLabel.fontSize = 18;
scoreLabel.fontColor = [UIColor blackColor];
scoreLabel.position = CGPointMake(200, 300);
[self addChild: scoreLabel];
Now, you can align the label with:
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
OR
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
OR
scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
This outputs are shown in figure below:
Keep coding............. :)
Hasn't been answered yet and I was just looking for this myself...
See the 2nd line...vertical alignment works the same way.
SKLabelNode *RunningLevelLabel = [SKLabelNode labelNodeWithFontNamed:#"Chalkduster" ];
[RunningLevelLabel setHorizontalAlignmentMode:SKLabelHorizontalAlignmentModeCenter];
RunningLevelLabel.text = [NSString stringWithFormat:#"%i",numberOfBonusAlienPoints];
RunningLevelLabel.fontSize = 36;
RunningLevelLabel.position = CGPointMake(-10,-50); // offscreen
RunningLevelLabel.fontColor = [SKColor grayColor];
[StartScreenWindow addChild:RunningLevelLabel];
Can anyone suggest how to underline the title of a UIButton ? I have a UIButton of Custom type, and I want the Title to be underlined, but the Interface Builder does not provide any option to do so.
In Interface Builder when you select the Font Option for a Button, it provides option to select None, Single, Double, Color but none of these provide any changes to the Title on the Button.
Any help appreciated.
To use interface builder to underline, one has to:
Change it to attributed
Highlight the text in the Attributes inspector
Right click, choose Font and then Underline
Video someone else made
https://www.youtube.com/watch?v=5-ZnV3jQd9I
From iOS6 it is now possible to use an NSAttributedString to perform underlining (and anything else attributed strings support) in a much more flexible way:
NSMutableAttributedString *commentString = [[NSMutableAttributedString alloc] initWithString:#"The Quick Brown Fox"];
[commentString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [commentString length])];
[button setAttributedTitle:commentString forState:UIControlStateNormal];
Note: added this as another answer - as its a totally different solution to my previous one.
Edit:
oddly (in iOS8 at least) you have to underline the first character otherwise it doesn't work!
so as a workaround, set the first char underlined with clear colour!
// underline Terms and condidtions
NSMutableAttributedString* tncString = [[NSMutableAttributedString alloc] initWithString:#"View Terms and Conditions"];
// workaround for bug in UIButton - first char needs to be underlined for some reason!
[tncString addAttribute:NSUnderlineStyleAttributeName
value:#(NSUnderlineStyleSingle)
range:(NSRange){0,1}];
[tncString addAttribute:NSUnderlineColorAttributeName value:[UIColor clearColor] range:NSMakeRange(0, 1)];
[tncString addAttribute:NSUnderlineStyleAttributeName
value:#(NSUnderlineStyleSingle)
range:(NSRange){5,[tncString length] - 5}];
[tncBtn setAttributedTitle:tncString forState:UIControlStateNormal];
UIUnderlinedButton.h
#interface UIUnderlinedButton : UIButton {
}
+ (UIUnderlinedButton*) underlinedButton;
#end
UIUnderlinedButton.m
#implementation UIUnderlinedButton
+ (UIUnderlinedButton*) underlinedButton {
UIUnderlinedButton* button = [[UIUnderlinedButton alloc] init];
return [button autorelease];
}
- (void) drawRect:(CGRect)rect {
CGRect textRect = self.titleLabel.frame;
// need to put the line at top of descenders (negative value)
CGFloat descender = self.titleLabel.font.descender;
CGContextRef contextRef = UIGraphicsGetCurrentContext();
// set to same colour as text
CGContextSetStrokeColorWithColor(contextRef, self.titleLabel.textColor.CGColor);
CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender);
CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender);
CGContextClosePath(contextRef);
CGContextDrawPath(contextRef, kCGPathStroke);
}
#end
You can do it in the interface builder itself.
Select the attribute inspector
Change the title type from plain to attributed
Set appropriate font size and text alignment
Then select the title text and set the font as underlined
It is very simple with attributed string
Creates a dictionary with set attributes and apply to the attributed string. Then you can set the attributed string as attibutedtitle in uibutton or attributedtext in uilabel.
NSDictionary *attrDict = #{NSFontAttributeName : [UIFont
systemFontOfSize:14.0],NSForegroundColorAttributeName : [UIColor
whiteColor]};
NSMutableAttributedString *title =[[NSMutableAttributedString alloc] initWithString:#"mybutton" attributes: attrDict];
[title addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0,[commentString length])]; [btnRegLater setAttributedTitle:title forState:UIControlStateNormal];
Here is my function, works in Swift 1.2.
func underlineButton(button : UIButton, text: String) {
var titleString : NSMutableAttributedString = NSMutableAttributedString(string: text)
titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: NSMakeRange(0, count(text.utf8)))
button.setAttributedTitle(titleString, forState: .Normal)
}
UPDATE Swift 3.0 extension:
extension UIButton {
func underlineButton(text: String) {
let titleString = NSMutableAttributedString(string: text)
titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, text.characters.count))
self.setAttributedTitle(titleString, for: .normal)
}
}
The Swift 5.0 version that works as of September 2019 in Xcode 10.3:
extension UIButton {
func underlineText() {
guard let title = title(for: .normal) else { return }
let titleString = NSMutableAttributedString(string: title)
titleString.addAttribute(
.underlineStyle,
value: NSUnderlineStyle.single.rawValue,
range: NSRange(location: 0, length: title.count)
)
setAttributedTitle(titleString, for: .normal)
}
}
To use it, set your button title first with button.setTitle("Button Title", for: .normal) and then call button.underlineText() to make that title underlined.
Nick's answer is a great, quick way to do this.
I added support in drawRect for shadows.
Nick's answer doesn't take into account if your button title has a shadow below the text:
But you can move the underline down by the height of the shadow like so:
CGFloat descender = self.titleLabel.font.descender;
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGFloat shadowHeight = self.titleLabel.shadowOffset.height;
descender += shadowHeight;
Then you'll get something like this:
For Swift 3 the following extension can be used:
extension UIButton {
func underlineButton(text: String) {
let titleString = NSMutableAttributedString(string: text)
titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, text.characters.count))
self.setAttributedTitle(titleString, for: .normal)
}
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
CGRect textRect = self.titleLabel.frame;
// need to put the line at top of descenders (negative value)
CGFloat descender = self.titleLabel.font.descender;
CGContextRef contextRef = UIGraphicsGetCurrentContext();
UIColor *colr;
// set to same colour as text
if (self.isHighlighted || self.isSelected) {
colr=self.titleLabel.highlightedTextColor;
}
else{
colr= self.titleLabel.textColor;
}
CGContextSetStrokeColorWithColor(contextRef, colr.CGColor);
CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender);
CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender);
CGContextClosePath(contextRef);
CGContextDrawPath(contextRef, kCGPathStroke);
}
//Override this to change the underline color to highlighted color
-(void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
// [self setNeedsDisplay];
}
Expanding on the answer by #Nick H247, I experienced an issue where firstly the underline was not redrawing when the button resized on rotation; this can be solved by setting your button to redraw like so:
myButton.contentMode = UIViewContentModeRedraw;
This forces the button to redraw when the bounds change.
Secondly, the original code assumed you only had 1 line of text in the button (my button wraps to 2 lines on rotation) and the underline only appears on the last line of text. The drawRect code can be modified to first calculate the number of lines in the button, then put an underline on every line rather than just the bottom, like so:
- (void) drawRect:(CGRect)rect {
CGRect textRect = self.titleLabel.frame;
// need to put the line at top of descenders (negative value)
CGFloat descender = self.titleLabel.font.descender;
CGContextRef contextRef = UIGraphicsGetCurrentContext();
// set to same colour as text
CGContextSetStrokeColorWithColor(contextRef, self.titleLabel.textColor.CGColor);
CGSize labelSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font
constrainedToSize:self.titleLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGSize labelSizeNoWrap = [self.titleLabel.text sizeWithFont:self.titleLabel.font forWidth:self.titleLabel.frame.size.width lineBreakMode:UILineBreakModeMiddleTruncation ];
int numberOfLines = abs(labelSize.height/labelSizeNoWrap.height);
for(int i = 1; i<=numberOfLines;i++) {
// Original code
// CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender + PADDING);
//
// CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender);
CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + (labelSizeNoWrap.height*i) + descender + PADDING);
CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + (labelSizeNoWrap.height*i) + descender);
CGContextClosePath(contextRef);
CGContextDrawPath(contextRef, kCGPathStroke);
}
}
Hope this code helps someone else!
In swift
func underlineButton(button : UIButton) {
var titleString : NSMutableAttributedString = NSMutableAttributedString(string: button.titleLabel!.text!)
titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: NSMakeRange(0, button.titleLabel!.text!.utf16Count))
button.setAttributedTitle(titleString, forState: .Normal)}
You can use this code to add underline with spacing in button.
When I tried to draw an underline from interface builder. It look like below image.
1 - Interface builder reference
And after using below code I achieved the result as I wanted.
2 - using described code
public func setTextUnderline()
{
let dummyButton: UIButton = UIButton.init()
dummyButton.setTitle(self.titleLabel?.text, for: .normal)
dummyButton.titleLabel?.font = self.titleLabel?.font
dummyButton.sizeToFit()
let dummyHeight = dummyButton.frame.size.height + 3
let bottomLine = CALayer()
bottomLine.frame = CGRect.init(x: (self.frame.size.width - dummyButton.frame.size.width)/2, y: -(self.frame.size.height - dummyHeight), width: dummyButton.frame.size.width, height: 1.0)
bottomLine.backgroundColor = self.titleLabel?.textColor.cgColor
self.layer.addSublayer(bottomLine)
}
How will one handle the case when we keep a button underlined pressed? In that case the button's textcolor changes according to highlighted color but line remains of original color. Let say if button text color in normal state is black then its underline will also have black color. The button's highlighted color is white. Keeping button pressed changes button text color from black to white but underline color remains black.
I believe it's some bug in font editor in XCode. If you using interface builder you have to change title from Plain to Attributed, open TextEdit create underlined text and copy-paste to textbox in XCode
Nick H247's answer but Swift approach:
import UIKit
class UnderlineUIButton: UIButton {
override func drawRect(rect: CGRect) {
super.drawRect(rect)
let textRect = self.titleLabel!.frame
var descender = self.titleLabel?.font.descender
var contextRef: CGContextRef = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(contextRef, self.titleLabel?.textColor.CGColor);
CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender!);
CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender!);
CGContextClosePath(contextRef);
CGContextDrawPath(contextRef, kCGPathStroke);
}
}
func underline(text: String, state: UIControlState = .normal, color:UIColor? = nil) {
var titleString = NSMutableAttributedString(string: text)
if let color = color {
titleString = NSMutableAttributedString(string: text,
attributes: [NSForegroundColorAttributeName: color])
}
let stringRange = NSMakeRange(0, text.characters.count)
titleString.addAttribute(NSUnderlineStyleAttributeName,
value: NSUnderlineStyle.styleSingle.rawValue,
range: stringRange)
self.setAttributedTitle(titleString, for: state)
}
Swift 3 version for #NickH247's answer with custom underline color, linewidth and gap:
import Foundation
class UnderlinedButton: UIButton {
private let underlineColor: UIColor
private let thickness: CGFloat
private let gap: CGFloat
init(underlineColor: UIColor, thickness: CGFloat, gap: CGFloat, frame: CGRect? = nil) {
self.underlineColor = underlineColor
self.thickness = thickness
self.gap = gap
super.init(frame: frame ?? .zero)
}
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let textRect = titleLabel?.frame,
let decender = titleLabel?.font.descender,
let context = UIGraphicsGetCurrentContext() else { return }
context.setStrokeColor(underlineColor.cgColor)
context.move(to: CGPoint(x: textRect.origin.x, y: textRect.origin.y + textRect.height + decender + gap))
context.setLineWidth(thickness)
context.addLine(to: CGPoint(x: textRect.origin.x + textRect.width, y: textRect.origin.y + textRect.height + decender + gap))
context.closePath()
context.drawPath(using: .stroke)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}