我正在开发一个简单的应用程序来在表格视图中显示项目。如果我从UITableViewCell
返回一个普通的tableView:cellForRowAtIndexPath
对象:
static NSString *cellIdentifier = @"EmailCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"EmailCell"];
}
cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
...然后与动态文本的交互按预期工作;如果用户转到Settings | General | Text Size
,更改滑块值,然后返回到我的应用程序,所有可见单元格立即更新自己以使用新的字体大小。
但是,如果我返回UITableViewCell的自定义子类,其中XIB包含设置为使用文本样式而不是系统字体的UILabel
,则动态文本无法正常工作。以下是我用来将{XIB»分配给viewDidLoad
中的表格的代码:
[self.table registerNib:[UINib nibWithNibName:@"EmailCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:@"EmailCell"];
然后在tableView:cellForRowAtIndexPath:
static NSString *cellIdentifier = @"EmailCell";
EmailCell *cell = (EmailCell *)[tableView
dequeueReusableCellWithIdentifier:cellIdentifier];
首次运行应用时,可见单元格的文本大小与用户选择的首选文本大小相匹配。但是,如果我转到设置并更改该大小然后返回到我的应用程序,则所有可见单元格都保留以前的文本大小。如果我然后向上滚动,我会看到两个单元格显示新的(正确的)文本大小,但其余的仍然是旧的大小。如果我停止并重新启动应用程序,现在所有单元格都会显示新的(正确的)文本大小。
对我来说,似乎很明显,tableview将先前大小的单元格保留在队列中,而不是自动更新其字体大小以响应用户对首选文本大小的更改。但是我不明白为什么tableview 在队列包含普通的非子类UITableViewCell
实例时自动进行此更改。有没有什么办法可以让我无需重新启动应用程序就可以工作(或者不重新创建UITableView
实例,从而清空队列)?有没有办法以编程方式(并合法地)清除此队列?
编辑:如果有人对这个问题感兴趣,我的插件修补就是编写一个通用的实用工具方法来创建一个新的tableview,复制原始tableview中的所有相关属性(包括注册的单元类)然后将旧的交换为旧的。由于这是一个新表,因此它会生成包含新文本大小的排队单元格的全新实例。
答案 0 :(得分:1)
现在可以在iOS 10中为您处理。
http://useyourloaf.com/blog/auto-adjusting-fonts-for-dynamic-type/
在您的标签上将adjustsFontForContentSizeCategory
设置为YES
/ true
,当文字大小首选项更改时,它会自动调整大小。
答案 1 :(得分:0)
根据您所描述的内容,您可能只是想在用户对其进行背景化后,在视图返回屏幕时随时重新加载表格。为了实现这个我想你想要的方式,你需要在你的tableView的init方法中添加以下内容 - 它会告诉你的tableView在应用程序即将进入前台时正确地重新加载单元格:
[[NSNotificationCenter defaultCenter] addObserver:self.tableView selector:@selector(reloadData) name:UIApplicationWillEnterForegroundNotification object:nil];
这样,如果用户在转到手机设置后打开应用程序返回到视图,则应重新加载tableView并正确反映更改(如果有的话)。
您可以在此处看到我测试结果的快速视频:
https://www.dropbox.com/s/pvjuiyofydnxnvd/textsize.mov
编辑:
就像你在之前的评论中所说的那样,你的nib实现似乎有问题。唯一的区别是更新label属性的位置/方式。在自定义单元格中,我创建了一个label属性和一个font属性,并将标签添加到init中的单元格中,而在layoutSubviews中我覆盖了该字体。这是代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LabelCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LabelCell"];
if (cell == nil) {
cell = [[LabelCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"LabelCell"];
}
cell.myLabel.text = _items[indexPath.row];
cell.myFont = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
return cell;
}
在细胞本身:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
self.myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, self.contentView.frame.size.width - 20, 34)];
self.myLabel.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:self.myLabel];
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.myLabel.font = self.myFont;
}
以下是使用带标签的自定义单元格的相同结果:
https://www.dropbox.com/s/ow2zkb6j9yq2c3m/labelcells.mov
关于“清除队列”,单元格在它们即将显示在屏幕上之前不会排队,您可以通过在使用标识符将单元格出列后立即记录计数器值来查看。如果现在屏幕上有10个单元格,它只会使10个单元格出列。这就是为什么你使用代码if(!cell){在这里做所有单元格常见的东西}的原因然后你做了特定于每个单元格的事情,以及为什么这个代码工作,即使你假设reloadData没有“清除队列”,我不相信在阅读UITableView文档之后也不会这样做。
答案 2 :(得分:0)
我的直接修复方法是编写一个通用实用程序方法,该方法生成一个新的tableview,从原始tableview(包括已注册的单元类)复制所有相关属性,然后将旧的替换为旧的。由于这是一个新表,因此它会生成包含新文本大小的排队单元格的全新实例。