Swift 4 UnsafeMutablePointer ObjCBool parameter, how do you use it in a closure?
When enumerating the attributed string, there is a UnsafeMutablePointer<ObjCBool> parameter, and maybe you like me want to change it from false to true to stop something enumerating.
The syntax appears as follows;
{ (attributeDict: [NSAttributedStringKey: Any], theRange: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in
enumerateAttributes(in:……)… has a closure that has a ‘stop’ element. You might first think “I need to use the inout” but soon Xcode will flag this RED.
{ (attributeDict, theRange, stop) in
{ (attributeDict, theRange, _) in. // << many people skipped the last parameter by ignoring it
The quick info you need;
You simple access the ‘stop’ elements first element [0] and set it to ‘true’ to exit the closure/block of code.
‘stop[0]=true’
Here is the whole gist of the situation.
//: A UIKit based Playground for presenting A Textview with Attributed String text | |
//: Demonstrates the use of 'stop: UnsafeMutablePointer<ObjCBool>' parameter in the block of code by using 'stop[0]=true' | |
//: Show the assistant editor to see the Text view output. | |
// designed with Swift 4.1 | |
import UIKit | |
import PlaygroundSupport | |
class MyViewController : UIViewController { | |
override func loadView() { | |
let view = UIView() | |
view.backgroundColor = .white | |
let textView = UITextView() | |
textView.frame = CGRect(x: 5, y: 5, width: 365, height: 20 * 33) | |
view.addSubview(textView) | |
self.view = view | |
enum TaskType | |
{ | |
case kChangeColor | |
case kBoldenFont | |
} | |
let attributedString = NSMutableAttributedString(string: "Roses are red, violets are blue, this objcbool unsafemutable pointer takes time to get use to.") | |
for (task,searchWord,modifier) in [ | |
(task: TaskType.kBoldenFont, searchWord: "unsafemutable", modifier: nil ), | |
(task: TaskType.kChangeColor, searchWord: "red", modifier: UIColor.red ), | |
(task: TaskType.kChangeColor, searchWord: "blue", modifier: UIColor.blue ), | |
] | |
{ | |
if let swiftRange = attributedString.string.range(of: searchWord) | |
{ | |
let nsRange = NSRange(swiftRange, in: attributedString.string) | |
switch task | |
{ | |
case .kBoldenFont: | |
attributedString.addAttributes([NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 14)], range: nsRange) | |
case .kChangeColor: | |
if let theColor = modifier | |
{ | |
attributedString.addAttributes([NSAttributedStringKey.foregroundColor: theColor], range: nsRange) | |
} | |
} | |
} | |
} | |
//provided for reference | |
//attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.string.count),options: []) | |
//{ (attributeDict: [NSAttributedStringKey: Any], | |
// theRange: NSRange, | |
// stop: UnsafeMutablePointer<ObjCBool>) in | |
var idx = 0 | |
attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.string.count),options: []) | |
{ (attributeDict, theRange, stop) in | |
print(theRange) | |
print(attributeDict) | |
var thisKey = "" | |
if let aKey = attributeDict.keys.first | |
{ | |
print(aKey.rawValue) | |
thisKey = aKey.rawValue | |
} | |
print() | |
switch idx { | |
case 0: | |
break | |
case 1: | |
if thisKey == "NSColor" | |
{ | |
print("Color found at \(theRange.location) to \(theRange.length)") | |
} | |
default: | |
stop[0] = true | |
break | |
} | |
idx += 1 | |
} | |
textView.attributedText = attributedString | |
} | |
} | |
// Present the view controller in the Live View window | |
PlaygroundPage.current.liveView = MyViewController() | |