Swift 5.5 AttributedString doesn't show in interface - swift

Here's the Swift 5.5 way to make an attributed string:
let s = "Hello"
var attrib = AttributedString(s)
if let range = attrib.range(of: "ell") {
attrib[range].foregroundColor = .red
self.label.attributedText = NSAttributedString(attrib)
}
The problem is that the label doesn't show any red characters. In fact, I can print self.label.attributedText and I can see that the red color attribute didn't even make it into the NSAttributedString. What's going on?

By default, Swift thinks you're applying the SwiftUI attributes, which UIKit doesn't understand. You have to specify what kind of attributed string attribute this is:
attrib[range].uiKit.foregroundColor = .red
// ^^^^^

Related

How choose random element in swift?

I am absolutely new in swift and try to find a way for changing the color of labels randomly
for i in 1...20 {
let label = [label1, label2, label3]
let a = label.randomElement()
a.textColor = UIColor.orange // there is the problem
Any ideas?
Collection method randomElement() returns an optional. If your collection element is already optional you have a double optional. You need to use optional chaining or unwrap your optional.
a?.textColor = .orange // if your `a` label is of type `UILabel?` use a single exclamation mark

Error sintax UIColor(CGColor: selectedButton?.layer.backgroundColor) Swift

I am trying to follow a swift tutorial but I have the latest version and the tutorial is in the previous version. I can not solve the syntax because I do not know much about swift, I'm starting.
Line:
let color = UIColor(CGColor: selectedButton?.layer.backgroundColor)
Error:
Value of optional type CGColor= not unwrapped; did yoy mean to use '!' or '?' Replace selectedButton?.layer.backgroundColor with '(selectedButton?.layer.backgroundColor)!'
I already replaced for this:
let color = UIColor(CGColor: (selectedButton?.layer.backgroundColor)!)
next error now:
Ambiguous use of 'init(CGColor)'
The correct way to do it would be
if let color = selectedButton.backgroundColor {
// use color in here
}
But for tutorial purposes just use
let color = selectedButton.backgroundColor!

How to get the text out of a WKInterfaceLabel

It seems that labels are a bit different on the Apple Watch!
I have the following label created :
#IBOutlet weak var playerNameLabel: WKInterfaceLabel!
Then writing the label is no problem (with the "setText" method)
let someString = "Hello"
playerNameLabel.setText(someString)
But how do I get the text out of such a Label into a String-constant ???
I tried:
let plaerName_firstTrial: String = playerNameLabel.description // some weird stuff
let plaerName_secondTrial: String = playerNameLabel.text // error
let plaerName_thirdTrial: String = playerNameLabel // error
let plaerName_fourthTrial: String = ?????
WKInterfacLabel has only setter property and no getter property as defined by Apple.
Check this WKInterfaceLabel class declaration :
According to https://developer.apple.com/library/ios/documentation/WatchKit/Reference/WKInterfaceLabel_class/
They only seem to allow setting the text, not getting it (programmatically).

How to get multiple text colors for a single NSTextField in Swift?

textfield.stringValue = "This part red - here some blue"
All that inside one textfield in two different colors.
Could I put HTML code inside the textfield? Because I also want to provide a url link inside a textfield, so that would solve two problems.
Look into the NSMutableAttributedString class to achieve this.
Example:
attrString = NSMutableAttributedString(string: "Hello World", attributes: [NSFontAttributeName:UIFont(name: "Arial", size: 18.0)!])
attrString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange(location:0,length:2))
This example creates an NSMutableAttributedString and then adds an attribute that sets the string to have a red font color for the characters at location 0 to 2.
Documentation:
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableAttributedString_Class/index.html
There are methods for initializing an attributed string from HTML in the NSAttributedString App Kit Additions or UIKit Additions, as the case may be. (You didn't say whether you're doing Mac or iOS.) Once you have an NSAttributedString, assign it to the attributedStringValue property of the field.

NSFontAttributedString worked before XCode 6.1

let timeFont = [NSFontAttributeName:UIFont(name: "Voyage", size: 20.0)]
var attrString3 = NSAttributedString("(Time)", attributes : timeFont); // <--- compiler error "Extra argument in call"
This code worked in xcode 6.0, but now that I've upgraded to xcode 6.1 it doesn't work anymore and I can't figure out what I need to get it back working. It says that there is an extra argument, but that's not correct. I believe that it has something to do with the new failable initializers, but everything that I've tried doesn't' work.
There are two reasons your code is failing to compile:
The initializer for NSAttributedString that you want to use now requires the explicit labeling of the string parameter
The UIFont initializer that you are using now returns an optional (i.e., UIFont?), which needs to be unwrapped before you pass it in the attributes dictionary.
Try this instead:
let font = UIFont(name: "Voyage", size: 20.0) ?? UIFont.systemFontOfSize(20.0)
let attrs = [NSFontAttributeName : font]
var attrString3 = NSAttributedString(string: "(Time)", attributes: attrs)
Note the use of the new coalescing operator ??. This unwraps the optional Voyage font, but falls back to the System Font if Voyage is unavailable (which seems to be the case in the Playground). This way, you get your attributed string regardless, even if your preferred font can't be loaded.
Xcode 6.1 comes with Swift 1.1 that supports constructors that can fail. UIFont initialisation can fail and return nil. Also use string: when creating NSAttributedString:
if let font = UIFont(name: "Voyage", size: 20.0) {
let timeFont = [NSFontAttributeName:font]
var attrString3 = NSAttributedString(string: "(Time)", attributes : timeFont)
}