在@yaslam的帮助下,我在Core Text中创建了一个UILabel,它使用CTRubyAnnotation以水平和垂直的方式显示日语文本。不幸的是我有问题。我需要在自定义单元格中使用此标签,并且需要单元格根据文本动态调整单元格的高度。但不要工作。细胞不膨胀
你能帮助我吗?
非常感谢你
这是密码
import UIKit
protocol SimpleVerticalGlyphViewProtocol {
}
extension SimpleVerticalGlyphViewProtocol {
func drawContext(_ attributed:NSMutableAttributedString, textDrawRect:CGRect, isVertical:Bool) {
guard let context = UIGraphicsGetCurrentContext() else { return }
var path:CGPath
if isVertical {
context.rotate(by: .pi / 2)
context.scaleBy(x: 1.0, y: -1.0)
path = CGPath(rect: CGRect(x: textDrawRect.origin.y, y: textDrawRect.origin.x, width: textDrawRect.height, height: textDrawRect.width), transform: nil)
}
else {
context.textMatrix = CGAffineTransform.identity
context.translateBy(x: 0, y: textDrawRect.height)
context.scaleBy(x: 1.0, y: -1.0)
path = CGPath(rect: textDrawRect, transform: nil)
}
let framesetter = CTFramesetterCreateWithAttributedString(attributed)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, nil)
CTFrameDraw(frame, context)
}
}
class CustomLabel: UILabel, SimpleVerticalGlyphViewProtocol {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
override func drawText(in rect: CGRect) {
let attributed = NSMutableAttributedString(attributedString: self.attributedText!)
let isVertical = false // if Vertical Glyph, true.
attributed.addAttributes([NSAttributedStringKey.verticalGlyphForm: isVertical], range: NSMakeRange(0, attributed.length))
attributed.addAttribute(NSAttributedStringKey.font, value: UIFont(name: "Hiragino Mincho ProN", size: 27)!, range: NSMakeRange(0, attributed.length))
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 2
paragraphStyle.lineSpacing = 4
attributed.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, (attributed.length)))
drawContext(attributed, textDrawRect: rect, isVertical: isVertical)
}
}
TableView类
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
let label = cell.viewWithTag(10) as! CustomLabel
let attributedText = Utility.sharedInstance.furigana(String: "|銀行《ぎんこう》と|郵便局《ゆうびんきょく》の|間《あいだ》の|道《みち》をまっすぐ|行《い》くと、|学校《がっこう》の|前《まえ》に|出《で》ます。")
label.attributedText = attributedText
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
//return 70
}
结果是:
最佳答案
使用CoreText,视图的高度不会自动确定。
计算CoreText的绘图高度并将其设置为单元格中UIView的高度。
在情节提要中对UITableView进行以下设置。
*自动检查行高
*估算自动校验
对于程序,如下所示。
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = UITableViewAutomaticDimension
计算CoreText绘图高度的示例代码。
我不知道这是否是计算高度的最佳代码。
示例代码相当草率,所以请实际重构它。
import UIKit
class CoreTextWithTableViewController: UITableViewController {
var texts = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// tableView.rowHeight = UITableViewAutomaticDimension // or check Automatic of Row Height in storyboard
// tableView.estimatedRowHeight = UITableViewAutomaticDimension // or check Automatic of Estimate in storyboard
let text = "すでに|世界《せかい》で最も|先進的《せんしんてき》なモバイルオペレーティングシステムであるiOSに、iOS 11が新あらたな|基準《きじゅん》を打ち立てます。iPhoneは今まで以上に優れたものになり、iPadはかつてないほどの|能力《のうりょく》を手に入れます。さらにこれからはどちらのデバイスにも、ゲームやアプリケーションの|拡張現実《かくちょうげんじつ》のための驚くような|可能性《かのうせい》が広がります。iOS 11を|搭載《とうさい》するiPhoneとiPadは、間違いなくこれまでで最もパワフルで、最もパーソナルで、最も賢いデバイスです。"
let text2 = "すでに|世界《せかい》で最も|先進的《せんしんてき》なモバイルオペレーティングシステムであるiOSに、iOS 11が新あらたな|基準《きじゅん》を打ち立てます。iPhoneは今まで以上に優れたものになり、iPadはかつてないほどの|能力《のうりょく》を手に入れます。"
for _ in 0...20 {
texts.append(text)
texts.append(text2)
}
NotificationCenter.default.addObserver(self, selector: #selector(changeDirection(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return texts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCellWithCoreText
let text = texts[indexPath.row]
cell.coreTextView.text = text
let height = cell.coreTextView.heightOfCoreText()
cell.heightOfCoreTextView.constant = height
// Execute redraw
cell.coreTextView.setNeedsDisplay()
return cell
}
}
extension CoreTextWithTableViewController {
@objc func changeDirection(notification: NSNotification){
tableView.reloadData()
}
}
class CustomCellWithCoreText: UITableViewCell {
@IBOutlet weak var coreTextView: CustomViewWithCoreText!
@IBOutlet weak var heightOfCoreTextView: NSLayoutConstraint!
}
class CustomViewWithCoreText: UIView, SimpleVerticalGlyphViewProtocol {
var text: String = ""
lazy var attributed: NSMutableAttributedString = text.attributedStringWithRuby()
var height = CGFloat()
override func draw(_ rect: CGRect) {
let textDrawRect = CGRect(x: rect.origin.x, y: rect.origin.y, width: rect.size.width, height: height)
drawContext(attributed, textDrawRect: textDrawRect, isVertical: false)
}
/// get Height of CoreText Draw Rect
func heightOfCoreText() -> CGFloat {
// initialize height and attributed
height = CGFloat()
attributed = text.attributedStringWithRuby()
// MEMO: height = CGFloat.greatestFiniteMagnitude
let textDrawRect = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude)
let path = CGPath(rect: textDrawRect, transform: nil)
let framesetter = CTFramesetterCreateWithAttributedString(attributed)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, nil)
let anyArray: [AnyObject] = CTFrameGetLines(frame) as [AnyObject]
let lines = anyArray as! [CTLine]
for line in lines {
var ascent = CGFloat()
var descent = CGFloat()
var leading = CGFloat()
CTLineGetTypographicBounds(line, &ascent, &descent, &leading)
height += ceil(ascent + descent + leading)
}
return height
}
}
sample image
rotate tableView
CTParagraphStyle的设置值似乎没有反映在CTlineGettyPostBounds获得的高度中。
相反,使用CTFramesetterSuggestFrameSizeWithConstraints可以工作。
func heightOfCoreText() -> CGFloat {
// initialize height and attributed
height = CGFloat()
attributed = text.attributedStringWithRuby()
// MEMO: height = CGFloat.greatestFiniteMagnitude
let textDrawRect = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude)
let framesetter = CTFramesetterCreateWithAttributedString(attributed)
let frameSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, attributed.length), nil, textDrawRect.size, nil)
height = frameSize.height
return height
}
最小行距=10.0
线高倍数=1.5
关于ios - 具有核心文字的自定义UITableViewCell,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47636905/