How do I append two attributed strings with different fonts? - ios

Here I have tried to append two attributed strings in a single UILabel but I made some mistake so any one can find my mistake please?
let textFontAttributes = [
NSFontAttributeName : font,
// Note: SKColor.whiteColor().CGColor breaks this
NSForegroundColorAttributeName: UIColor.whiteColor(),
NSStrokeColorAttributeName: UIColor.blackColor(),
// Note: Use negative value here if you want foreground color to show
NSStrokeWidthAttributeName: -8]

This is the demo, you can have a try, In fact, you should provide more info of what the wrong is or what the error is.
var firstString = "Hello" as NSString
var secondString = " World" as NSString
var totalString = firstString.stringByAppendingString(secondString as String) as NSString
let firsttAttributes = [
NSFontAttributeName : UIFont.systemFontOfSize(16),
// Note: SKColor.whiteColor().CGColor breaks this
NSForegroundColorAttributeName: UIColor.whiteColor(),
NSStrokeColorAttributeName: UIColor.blackColor(),
// Note: Use negative value here if you want foreground color to show
NSStrokeWidthAttributeName: -8]
let secondAttributes = [
NSFontAttributeName : UIFont.systemFontOfSize(12),
// Note: SKColor.whiteColor().CGColor breaks this
NSForegroundColorAttributeName: UIColor.redColor(),
NSStrokeColorAttributeName: UIColor.blackColor(),
// Note: Use negative value here if you want foreground color to show
NSStrokeWidthAttributeName: -8]
var attributedString = NSMutableAttributedString(string: totalString as String, attributes: firsttAttributes)
var secondRange = totalString.rangeOfString(secondString as String)
if secondRange.location != NSNotFound {
attributedString.addAttributes(secondAttributes, range: secondRange)
}

Related

UIAlertaction button text alignment bug?

i have a problem with UIAlertAction text alignment , in IOS 10 when language isArabic .
sometimes the action sheet displayed in this way :
and some times it's displayed with this way:
this issue just with IOS 10, how could i set the textAlignmetCenter always ?
Thanks
I have successfully used the following, for both aligning and styling the text of UIAlertControllers:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.Center
let messageText = NSMutableAttributedString(
string: "The message you want to display",
attributes: [
NSParagraphStyleAttributeName: paragraphStyle,
NSFontAttributeName : UIFont.preferredFontForTextStyle(UIFontTextStyleBody),
NSForegroundColorAttributeName : UIColor.blackColor()
]
)
myAlert.setValue(messageText, forKey: "attributedMessage")
You can do a similar thing with the title, if you use "attributedTitle", instead of "attributedMessage"

why (arabic with english) text refuses to align right?

This is the string I use:
CASE 1
var word1 = "عبد الله"
var word2 = "restaurant"
label.text = " \(word1) found your review on \(word2) useful."
Result:
CASE 2
var word1 = "عبد الله"
var word2 = "restaurant"
label.text = "note: \(word1) found your review on \(word2) useful."
Result:
Question
so, how do I make the first word to wrap right? if the first word is arabic, it gets wrapped to the left, but if the first word is english the situation is expected, so how make the word1 to show up when first word on the left?
I tried both
label.textAlignment = NSTextAlignment.Left
and
label.textAlignment = NSTextAlignment.Natural
without any luck.
Unicode has two marker characters (LTR: 0x200E, RTL:200F). These are invisible, but control the direction, I just need to add this \u{200E} to force the wrapping direction.
\u{200E} \(word1) found your review on \(word2) useful.
EDIT:
see full tutorial here, for more info.
UILabel as a subclass of UIView has a variable named semanticContentAttribute which you can set to .foreRightToLeft, it can also be set from the nib inspector through the Semantic pop-up menu in the attributes inspector.
Moreover, you can query effectiveUserInterfaceLayoutDirection property for debugging it's state.
See this for reference.
Now if you need both alignments in one label it will be tricky, either group two labels in a container UIView or see if you can set these values for portions of an NSMutableAttributedString which you can feed to a UILabel.
The textAlignment properties you are trying to set will give you the same effect that MS-Word does to paragraph alignment but wouldn't flip reading direction for language.
Happy coding!
Edit: This is an example of what I am suggesting with attributed strings although when changing the arabic setting to RightToLeft it puts it at the bottom of the string... Maybe the flags need to be combined differently?
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
let myMutableString = NSMutableAttributedString()
//right-to-left
let multipleAttributes: [String : AnyObject] = [
NSForegroundColorAttributeName: UIColor.orangeColor(),
NSBackgroundColorAttributeName: UIColor.blueColor(),
NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue,
NSWritingDirectionAttributeName : [NSWritingDirection.LeftToRight.rawValue ]
]
let myAttrString = NSAttributedString(string: "عبد الله", attributes: multipleAttributes)
myMutableString.appendAttributedString(myAttrString)
//some-text
let someText = NSAttributedString(string: " finds ", attributes: nil)
myMutableString.appendAttributedString(someText)
//left-to-right
let multipleAttributes2: [String : AnyObject] = [
NSForegroundColorAttributeName: UIColor.blueColor(),
NSBackgroundColorAttributeName: UIColor.yellowColor(),
NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue,
NSWritingDirectionAttributeName : [NSWritingDirection.LeftToRight.rawValue | NSTextWritingDirection.Embedding.rawValue]
]
let myAttrString2 = NSAttributedString(string: "restaurant", attributes: multipleAttributes2)
myMutableString.appendAttributedString(myAttrString2)
label.attributedText = myMutableString
self.view.addSubview(label)
label.sizeToFit()
label.center = self.view.center
}

drawInRect text alignment using Swift

I am trying to put some text on top of an image that would be in the center of a CGRect which would be on top of that image. Here is a bit of code:
let textColor: UIColor = UIColor.whiteColor()
let textFont: UIFont = UIFont(name: "Helvetica Bold", size: 17
)!
let textAlignment = NSTextAlignment.Center
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
NSTextAlignment: textAlignment
]
myString.drawInRect(rect, withAttributes: textFontAttributes)
The problem is in the text alignment. When I write it like this I get an error:
Type of expression is ambiguous without more context
When I set key and value types to [String : AnyObject] the compiler complains again:
Cannot convert value of type 'NSTextAlignment.Type' to expected dictionary key type 'String'
Which I understand. I researched this for like two hours and haven't found any up to date solution and not single one how cloud one write this using Swift.
NSTextAlignment isn't a valid key. Note how the other keys end in Name. See the docs for NSFontAttributeName and NSForegroundColorAttributeName to see the list of valid keys.
Instead of NSTextAlignment you need to use NSParagraphStyleAttributeName which requires that you create an instance of NSParagraphStyle. That is where you set the alignment to .Center.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Center
The text alignment belongs to the paragraph style. Create a NSMutableParagraphStyle instance and pass it with key NSParagraphStyleAttributeName to the attributes.
let style = NSMutableParagraphStyle()
style.alignment = .Center
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: style
]

Way stroke outline number using swift

is there anyway to draw or stroke a number using swift for iOS? The number has to be in the outline style. Thanks in advance.
Use an NSAttributedString. UITextField can display attributed strings using the attributedText property.
let number = 5 // Whatever number you are looking to output
let font = UIFont.systemFontOfSize(12.0)
let attribs = [
NSForegroundColorAttributeName: UIColor.whiteColor(),
NSStrokeColorAttributeName: UIColor.blackColor(),
NSFontAttributeName: font,
NSStrokeWidthAttributeName: 1.0
]
let outlinedNumber = NSAttributedString(string: "\(number)", attributes: attribs)
Play with the various attributes to get the effect you want.

Append readmore label after 120 char, and make it clickable in ios

The data is coming from parser, if the text is more than 120 char then it should append "...ReadMore" just like facebook. I have got the code for appending text, but dont know how to make clickable link. I'm using Swift Languange.
if cell!.bhikmangaTextlbl!.text!.utf16Count >= 120
{
var abc : String = (cell!.bhikmangaTextlbl!.text! as
NSString).substringWithRange(NSRange(location: 0, length: 120))
abc += " ...ReadMore"
cell!.bhikmangaTextlbl!.text = abc
}
#Mihir Mehta, This is code i have implemented.
var bhikmangaTextlbl:UITextView?
if cell!.bhikmangaTextlbl!.text!.utf16Count >= 120
{
var abc : String = (cell!.bhikmangaTextlbl!.text! as NSString).substringWithRange(NSRange(location: 0, length: 120))
abc += "...ReadMore"
cell!.bhikmangaTextlbl!.text = abc
var attribs = [NSForegroundColorAttributeName: UIColor.blackColor(), NSFontAttributeName: UIFont.systemFontOfSize(14.0)]
var attributedString: NSMutableAttributedString = NSMutableAttributedString(string: abc, attributes: attribs)
attributedString.addAttribute(NSLinkAttributeName, value: "...ReadMore", range: NSRange(location: 120, length: 11))
attributedString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: NSRange(location: 120, length: 11))
cell!.bhikmangaTextlbl!.attributedText = attributedString
}
//The function you said i have written here
func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool
{
return true
}
You can use attributed string here ... and make some part of text clickable
here is Objective C code. You can write same for Swift
NSDictionary *attribs = #{
NSForegroundColorAttributeName: BODY_FONT_COLOR,
NSFontAttributeName: [UIFont fontWithName:FontHelvetica size:AppFont16]
};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:ACCIDENT_DETECTION_AUTOMATIC_TEXT attributes:attribs];
[attributedString addAttribute:NSLinkAttributeName
value:#"Accident detection"
range:[[attributedString string] rangeOfString:#"Read More"]];
NSDictionary *linkAttributes = #{NSForegroundColorAttributeName: LINKS_FONT_COLOR,
NSUnderlineColorAttributeName: [UIColor clearColor],
NSUnderlineStyleAttributeName: #(NSUnderlineStyleNone)};
// assume that textView is a UITextView previously created (either by code or Interface Builder)
self.accidentDetectionText.linkTextAttributes = linkAttributes; // customizes the appearance of links
self.accidentDetectionText.attributedText = attributedString;
Well i would prefer adding an extra label titled "Read more" and adding the tap gesture on that for expanding the first label.

Resources