Closed alamodey closed 3 years ago
Can you provide sample code of your configuring the label?
import UIKit
import CoreText
import ZSWTappableLabel
class ViewController: UIViewController, ZSWTappableLabelTapDelegate, ZSWTappableLabelLongPressDelegate {
@IBOutlet var textLabel: ZSWTappableLabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
textLabel.tapDelegate = self
textLabel.longPressDelegate = self
let word = "食べ物"
let ruby = "たべもの"
let attributes: [NSAttributedString.Key: Any] = [
.tappableRegion: true,
//.tappableHighlightedBackgroundColor: UIColor.lightGray,
//.tappableHighlightedForegroundColor: UIColor.white,
//kCTRubyAnnotationAttributeName as NSAttributedString.Key: annotation,
.foregroundColor: UIColor.blue,
//.font: UIFont.systemFont(ofSize: 32)
//.underlineStyle: NSUnderlineStyle.single.rawValue
]
//textLabel.attributedText = NSAttributedString(string: word, attributes: attributes)
var text = furigana(main: word, furigana: ruby)
text.addAttributes(attributes, range: NSMakeRange(0, text.length))
textLabel.attributedText = text
}
func tappableLabel(_ tappableLabel: ZSWTappableLabel, tappedAt idx: Int, withAttributes attributes: [NSAttributedString.Key : Any] = [:]) {
print("tapped at: ", idx)
}
func tappableLabel(_ tappableLabel: ZSWTappableLabel, longPressedAt idx: Int, withAttributes attributes: [NSAttributedString.Key : Any]) {
print("long-pressed at: ", idx)
}
func furigana(main: String, furigana: String) -> NSMutableAttributedString {
var ruby = furigana
var unmanage = Unmanaged.passRetained(ruby as CFString)
defer { unmanage.release() }
var text: [Unmanaged<CFString>?] = [unmanage, .none, .none, .none]
let rubyAttribute: [AnyHashable: Any] = [
kCTRubyAnnotationSizeFactorAttributeName: 0.5,
kCTForegroundColorAttributeName: UIColor.black
]
let annotation = CTRubyAnnotationCreateWithAttributes(.auto, .auto, .before, ruby as CFString, rubyAttribute as CFDictionary)
let attributed = NSMutableAttributedString(
string: main,
attributes: [kCTRubyAnnotationAttributeName as NSAttributedString.Key: annotation,
.foregroundColor: UIColor.blue,
])
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.0
paragraphStyle.lineSpacing = 12
attributed.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributed.length))
attributed.addAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 32)],range: NSMakeRange(0, (attributed.length)))
return attributed
}
}
The desired visual output is when you comment out .tappableRegion: true , which defeats the purpose of using this custom label as I want to detect taps and long presses on specific regions. Thanks!
With tappable region disabled:
With tappable region enabled:
I do not believe this is an issue with ZSWTappableLabel. If you instead use directly UILabel
in your example, it still will not render the second layer of text; this happens even when using an attribute key outside of ZSWTappableLabel, such as the following:
.init("test"): true,
Nothing immediately jumps out at me as to why this is happening. I tried replacing keys/values with CF equivalents (e.g. kCFBooleanTrue) but it didn't work. It must be tripping some weird code path in TextKit. This also still occurs if you draw yourself:
// overriding text drawing in ZSWTappableLabel to see what it looks like here
- (void)drawTextInRect:(CGRect)rect
{
[self performWithTouchHandling:^(ZSWTappableLabelTouchHandling *th) {
[th.layoutManager drawGlyphsForGlyphRange:NSMakeRange(0, th.unmodifiedAttributedString.length)
atPoint:th.pointOffset];
}];
}
I suggest filing a Technical Support Incident with Apple to see if they can help you find a workaround, that's probably your best bet if you want to be able to use attributed string keys alongside these ruby values.
It might also be worth seeing if a straight-Objective-C (rather than Swift) implementation works.
I've got a UILabel with ruby text using kCTRubyAnnotationAttributeName, but once I wrap it in ZSWTappableLabel, the ruby text disappears. Since ZSWTappableLabel is a subclass of UILabel, is it meant to eliminate the ability to create ruby text with kCTRubyAnnotationAttributeName?