Objective c 如何在UITableViewCell的UITextView中一致地绘制NSAttribute字符串

Objective c 如何在UITableViewCell的UITextView中一致地绘制NSAttribute字符串,objective-c,uitableview,uikit,uitextview,nsattributedstring,Objective C,Uitableview,Uikit,Uitextview,Nsattributedstring,我无法使用NSAttributedString从UITableViewCell中的UITextView获得一致的结果 内部-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath: UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if

我无法使用NSAttributedString从UITableViewCell中的UITextView获得一致的结果

内部-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    headerText = [[UITextView alloc]initWithFrame:CGRectZero];
    [headerText setUserInteractionEnabled:NO];
    headerText.tag = HEADER_TEXT;
    [cell.contentView addSubview:headerText]; 
} else {
    headerText = (UITextView*)[cell.contentView viewWithTag:HEADER_TEXT];
}

//...setting up attributed strings


[headerText setAttributedText:headerString];

CGSize headerSize = [headerText sizeThatFits:CGSizeMake(246, CGFLOAT_MAX)];

headerText.frame = CGRectMake(45, 8, headerSize.width, headerSize.height);
结果:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    headerText = [[UITextView alloc]initWithFrame:CGRectZero];
    [headerText setUserInteractionEnabled:NO];
    headerText.tag = HEADER_TEXT;
    [cell.contentView addSubview:headerText]; 
} else {
    headerText = (UITextView*)[cell.contentView viewWithTag:HEADER_TEXT];
}

//...setting up attributed strings


[headerText setAttributedText:headerString];

CGSize headerSize = [headerText sizeThatFits:CGSizeMake(246, CGFLOAT_MAX)];

headerText.frame = CGRectMake(45, 8, headerSize.width, headerSize.height);

如您所见,前两个似乎以我期望/想要的方式绘制文本。在最后两个示例中,UITextView sizeThatFits方法返回的大小比绘制文本所需的大得多,文本在框架中居中,而不是紧靠框架顶部。这是一个问题,因为我希望能够基于uitextview框架高度布局其他视图

从帧外滚回帧后:

现在更奇怪的是,当单元格被重用时,属性字符串被再次设置。uitextview以不一致的方式绘制文本

甚至将contentInsets设置为

headerText.contentInset = UIEdgeInsetsMake(-8, -8, -8, -8);
不提供任何类型的一致结果:

使用contentinset设置滚动后:


UITextView上是否有其他属性允许我获得所需的行为

设置以前具有不同属性字符串的UITextView的属性字符串时,必须始终首先将UITextView的所有与字符串相关的属性设置为nil,例如:

self.tv.text = nil;
self.tv.font = nil;
self.tv.textColor = nil;
self.tv.textAlignment = NSTextAlignmentLeft;
self.tv.attributedText = s2;
否则,正如您所发现的,以前属性化字符串的旧特性仍然存在,并影响新的属性化字符串


不过,总的来说,我不得不说我根本不明白为什么要使用UITextView。如果您不需要用户能够编辑这些属性字符串,请使用UILabel,或者直接绘制属性字符串,以获得尽可能精确的渲染效果。NSAttributedString为您提供了测量大小并在该大小内绘制所需的所有功能。

我使用UITextView是因为它实现了UITExport协议。它允许我在文本的某些子字符串上创建按钮。我承认直接画文本是有利的。为了实现这一点,我应该深入研究哪些iOS库?再次感谢您回答这个问题。不需要“库”来绘制文本。这是UIKit的一部分。我想我可能需要使用CoreText来确定触摸是否出现在给定行或一段文本的顶部。最后我找到了这个!谢谢